Task Scheduler looks like a simulation problem — "arrange the tasks on a timeline" — but the trick is that you never build the timeline. A little counting and one formula give the answer instantly.
Problem. You are given a list of tasks (each a letter) and an integer n: the cooldown, the
minimum number of intervals that must pass before the same task runs again. Each interval runs one task
or sits idle. Return the least number of intervals needed to finish every task.
Example: tasks = [A, A, A, B, B, B], n = 2 → answer 8 (one valid plan: A B idle A B idle A B).
The slow way first
The obvious idea: actually schedule it. Repeatedly pick the task with the most remaining copies that is off cooldown, place it, advance the clock, and insert idles when nothing is ready. With a heap this works, but it is fiddly and runs in O(total intervals) with a lot of bookkeeping.
The question to ask: what actually decides the length? Only the most frequent task does. It is the one forced to wait through cooldowns; everything else fits into the gaps it leaves behind.
The idea: the most frequent task builds a skeleton
Suppose the most frequent task appears maxFreq times. Picture it laid out in frames of width n + 1 — the task itself plus enough room for the cooldown. There are maxFreq - 1 full frames (the gaps between consecutive copies), and then a final placement of every task tied for the maximum.
The total is (maxFreq - 1) * (n + 1) + countOfMax. But if there are so many distinct tasks that every gap fills up with real work, no idle is ever needed and the answer is simply len(tasks). So we take the larger of the two.
Walk through it
Step through the animation. We count A and B (each 3 times), so maxFreq = 3 and countOfMax = 2. Two full frames of width n + 1 = 3 appear, each ending in an idle slot because there is no third task to fill it. Then a final row places one A and one B with no trailing idle. Count the slots: 2 × 3 + 2 = 8.
Pseudocode
count how often each task appears
maxFreq = the largest of those counts
countOfMax = how many tasks tie for that largest count
slots = (maxFreq - 1) * (n + 1) # full frames forced by cooldown
slots = slots + countOfMax # final placement, no trailing idle
return max(len(tasks), slots) # never less than just running them allThe Python solution
def least_interval(tasks, n):
from collections import Counter
counts = Counter(tasks)
max_freq = max(counts.values())
count_of_max = sum(1 for c in counts.values()
if c == max_freq)
slots = (max_freq - 1) * (n + 1)
slots += count_of_max
return max(len(tasks), slots)Counter(tasks)gives the frequency of every task in one pass.max_freqis how often the busiest task runs — it sets the skeleton.count_of_maxcounts the tasks tied for that maximum; they share the final, idle-free row.(max_freq - 1) * (n + 1)is themaxFreq - 1full frames, eachn + 1wide.- We add
count_of_maxfor the last placement, then takemaxwithlen(tasks)so a task-dense input that needs no idle is handled correctly.
Complexity
| Case | Time | Notes |
|---|---|---|
| Heap simulation | O(T log 26) (moderate) | T = total intervals, fiddly |
| Counting formula (this solution) | O(T) (moderate) | one pass to count, then O(1) |
O(1) (fast)We count the tasks once and then do constant arithmetic. Because there are at most 26 distinct task letters, the space is effectively O(1) — a fixed-size frequency table.
When this pattern shows up
When a scheduling or arrangement problem has a cooldown / minimum-gap rule, the answer is almost always driven by the single most frequent element. Count frequencies first and look for a closed-form formula before reaching for a simulation or heap.
Do not forget the max(len(tasks), slots). If you have many distinct tasks, the gaps fill with real work
and the formula can undercount — the true answer is just running every task back to back, which is
len(tasks).
Practice
For tasks = [A, A, A, B, B, B] and n = 2, what are maxFreq and countOfMax, and what does the formula give?
1. Which task determines the length of the schedule?
2. Why does each full frame have width n + 1?
3. Why do we take max(len(tasks), slots)?
4. What is countOfMax in (maxFreq − 1) × (n + 1) + countOfMax?