The problem
You get a list of tasks, each a capital letter, and a cooldown n. The CPU runs one task per time slot, or sits idle. Two runs of the same task must be at least n slots apart. Return the minimum number of slots needed to finish every task. Tasks can run in any order.
Input: tasks = ["A","A","A","B","B","B"], n = 2
Output: 8One best schedule is A B idle A B idle A B. Each A is 3 slots after the previous A, and two idle slots can’t be avoided.
How to think about it
Start with the simulation. At each slot, run the available task with the most remaining copies (a max-heap of counts), and park used tasks in a cooldown queue until they’re ready again. That’s the heap approach, and it works in O(total slots · log 26). But it simulates every idle slot one by one, and the answer can be worked out directly.
The key insight: the most frequent task decides the shape. Say A appears maxf times. Its copies must be spread out, so the schedule looks like maxf - 1 blocks of length n + 1 (an A followed by n slots of cooldown), then one final A. That’s (maxf - 1) * (n + 1) + 1 slots, and you can’t go lower.
Ties add to the tail. If several tasks share the top count maxf (here A and B), each one needs a place in the last block as well. So the frame is (maxf - 1) * (n + 1) + maxcount, where maxcount is how many tasks tie for the top. Every other task has fewer copies, so it fits into the idle gaps of the frame without breaking any cooldown.
When there are no idle slots left. With many different tasks, the gaps fill up and the frame overflows. Then nothing ever has to wait, and the answer is just len(tasks). So the answer is the larger of the two. Which pattern is this? It sits in the heaps lesson because the simulation uses a max-heap of counts, and it reappears under greedy. The tell is “most frequent first, with a cooldown”.
Approach
- Count each task.
- Let
maxfbe the highest count andmaxcountthe number of tasks with that count. - Compute the frame size
(maxf - 1) * (n + 1) + maxcount. - Return the larger of that and
len(tasks).
Solution
from collections import Counter
def least_interval(tasks, n):
cnt = Counter(tasks); maxf = max(cnt.values())
maxcount = sum(1 for v in cnt.values() if v == maxf) # tasks tied for the top count
return max(len(tasks), (maxf - 1) * (n + 1) + maxcount) # frame, unless tasks overflow it
# least_interval(["A","A","A","B","B","B"], 2) -> 8The same solution appears in the greedy practice set; the logic is identical.
Dry run
Three inputs, showing both sides of the max:
| Tasks | n |
Counts | maxf |
maxcount |
Frame | len |
Answer |
|---|---|---|---|---|---|---|---|
| AAABBB | 2 | A:3, B:3 | 3 | 2 | 2·3 + 2 = 8 | 6 | 8 |
| AAABBB | 0 | A:3, B:3 | 3 | 2 | 2·1 + 2 = 4 | 6 | 6 |
| AAABBBCCDDE | 2 | A:3, B:3, C:2, D:2, E:1 | 3 | 2 | 8 | 11 | 11 |
In the first row, the frame needs idle time. In the last two, the tasks overflow the frame, so no slot is ever idle.
Complexity
- Time: O(n) in the number of tasks. Counting is one pass; the rest looks at at most 26 counts.
- Space: O(1). The counter holds at most 26 letters.
Edge cases and pitfalls
n = 0: no cooldown, so the answer is alwayslen(tasks). Themaxhandles it.- One task type,
["A","A","A","A"]withn = 3: the frame is3 · 4 + 1 = 13, almost all idle. - Forgetting the ties. Using
+ 1instead of+ maxcountgives 7 on the example instead of 8. - Forgetting
len(tasks). Without themax, many distinct tasks give an answer that is too small. - The heap simulation is a fine answer if you can’t recall the formula. It’s also what you need if the question asks for the schedule itself, not just its length.
Related problems
- Reorganize String (LeetCode 767): the same idea with cooldown 1, where you must build the actual string.
- Last Stone Weight (LeetCode 1046): a straightforward max-heap simulation.
- Top K Frequent Elements (LeetCode 347): another problem that starts with counting frequencies.
- 1.Last Stone Weight (LeetCode 1046)
- 2.Kth Largest Element in a Stream (LeetCode 703)
- 3.Kth Largest Element in an Array (LeetCode 215)
- 4.Top K Frequent Elements (LeetCode 347)
- 5.K Closest Points to Origin (LeetCode 973)
- 6.Task Scheduler (LeetCode 621)
- 7.Reorganize String (LeetCode 767)
- 8.Sort Characters By Frequency (LeetCode 451)
- 9.Find K Pairs with Smallest Sums (LeetCode 373)
- 10.Merge k Sorted Lists (LeetCode 23)
- 11.Find Median from Data Stream (LeetCode 295)