Greedy
When one element has no options
The strongest kind of greedy argument: the choice is not best, it is the only one available.
Key idea
Find the element with no freedom
Exchange arguments justify choices that could have gone another way. Some problems have a stronger property: one element has exactly one possible role, so no argument is needed at all.
Look for it. When every value must be grouped into consecutive runs of a fixed size, the smallest remaining value cannot be in the middle or at the end of any run, because that would require something smaller that does not exist. It must start a run.
That is forced, not chosen. Everything else follows by repetition.
Below, the smallest remaining value is taken twice in a row, and each time the run it is forced to start is removed from the counts.
Tip
Handle all copies of a value at once
If a value appears three times, all three must start runs, and those runs are identical. Processing them one at a time repeats the same work; subtracting the whole count in one go is both faster and easier to reason about.
That is why the inner loop subtracts needed rather than one. Whenever a greedy step applies uniformly to a group, doing the group at once usually simplifies the code as well as the complexity.
Tip
The cheap impossibility check first
If the count does not divide evenly by the run size, no arrangement exists and nothing else needs computing. Cheap global checks before the main work are the same habit as the total check in the last lesson.
It also guards the main loop from a class of inputs where a partial run would otherwise be silently accepted.
Gotcha
Iterate the distinct values in order, not the raw input
The argument depends on always taking the smallest remaining value. Iterating the original list in its given order breaks that and the forced-choice justification no longer applies.
Sorting the distinct values and skipping those already consumed is what implements smallest-remaining correctly. Skipping zero counts matters, since a value fully consumed by earlier runs must not start a new one.
Tip
A heap is the alternative
A min-heap of the remaining values gives the smallest at each step without sorting up front, which is preferable when values arrive over time rather than all at once.
For a fixed input, sorting once is simpler and the same complexity. Knowing which one the situation calls for is the Unit 9 lesson applied here.
Cost
Cost
Counting is linear, sorting the distinct values is O(d log d), and the double loop touches each distinct value once per run offset, so O(d times size) overall.
In the worst case that is O(n log n) dominated by the sort. State it that way rather than as the double loop, since the sort is what actually dominates.
Predict the output: the value with no choices
Given a multiset that must be split into runs of consecutive values, the smallest remaining value is examined. Type the three lines it prints.
Hand Of Straights
Read the constraints first and let them tell you what complexity is expected. Derive the approach, implement it, run the tests, and submit when it passes.