Solving Task Scheduler with Math
05/24/2026

First steps
Alright, what is this problem actually asking us? Well, it seems simple, given some array of characters that represent CPU tasks, return the minimum amount of execution steps needed such that duplicate tasks are separated by at least n other tasks. Also, you can use an "idle" task to fill in gaps where necessary.So far it's not clear what the mathematical solution should be. Our goal though is to find a pattern that we can predict with math, so let's look at a few test cases. I always find that going through test cases and typing out my thoughts and state about the problem helps me reason through it much better.Running through the first sample test case:test case 1
input: tasks = ["A", "A", "A", "B", "B", "B"], n = 2
output: 8
output: 8
test case 1 solution
["A", "B", "idle", "A", "B", "idle", "A", "B"]
test case 1 solution alternative
["B", "A", "idle", "B", "A", "idle", "B", "A"]
test case 2
input: tasks = ["A", "A", "A", "B", "B"], n = 2
output: 7
output: 7
test case 2 solution
["A", "B", "idle", "A", "B", "idle", "A"]
test case 2 pattern
["A", <>, <>, "A", <>, <>, "A"]
The pattern
After seeing this pattern, I decided to denote t to represent the count of the most frequent repeating CPU task. The first derivation I came up with is below:Minimum steps formula
Where:
The count of the most frequent CPU task
The cooling interval (minimum tasks between duplicates)
test case
input: tasks = ["A", "A", "A", "B", "B"], n = 2
output: 7
output: 7
t represents the count of the most frequent CPU task. In our case, that's A with a count of 3. So, why do we have (t - 1) in our formula? Let's remember back to the forced pattern of the answer for this example:pattern
["A", <>, <>, "A", <>, <>, "A"]
A tasks are present in our forced structure with the 2 "anything" slots [<>, <>]. We're essentially subtracting 1 occurrence of the most frequent CPU task because the last most frequent CPU task will go at the end alone, without a cool down period.In other words, we have 2 occurrences of "A", <>, <> and one lone occurrence at the end of A.If we didn't have t - 1 in our formula, we would be building 3 blocks of"A", <>, <> which would generate a pattern of:pattern without t - 1
["A", <>, <>, "A", <>, <>, "A", <>, <>]
n + 1 then? Let's look at the example this way:pattern with t - 1 only
["A", "A"]
A and subtracting its count by one (which ist - 1). Now we want to build the blocks of "A", <>, <>If we multiply n as is, we would get the following structure:pattern with (t - 1) * n
["A", <>, "A", <>]
(t - 1) * n which using our running example would be (3 - 1) * 2 = 4. In other words, n represents the recurring block size.From our visual example, we want the block size to be of size 3 which is "A", <>, <>It is true that from the input, n represents the cool down period, during which any tasks can run in the "anything" slots. However, in the mathematical representation, (n + 1) represents the recurring block size length, which is n "anything" slots plus the most frequent task.Putting those 2 pieces together, we have a formula that represents the following pattern:pattern with (t - 1) * (n + 1)
["A", <>, <>, "A", <>, <>]
A task at the end, which is what the + 1 is for at the end of our formula.pattern with (t - 1) * (n + 1) + 1
["A", <>, <>, "A", <>, <>, "A"]
test case 1
input: tasks = ["A", "A", "A", "B", "B", "B"], n = 2
output: 8
output: 8
A and B tasks had the same occurrence frequency, it wouldn't matter which one we chose as our most frequent task for the t variable. While that's true, the formula doesn't work, it's off by one:(t - 1) * (n + 1) + 1 would be (3 - 1) * (2 + 1) + 1 = 7 while the expected answer is 8. Let's take a look at the solution again for test case 1:test case 1 solution
["A", "B", "idle", "A", "B", "idle", "A", "B"]
test case 1 pattern
["A", <>, <>, "A", <>, <>, "A", <>]
test case 1 pattern from formula
["A", <>, <>, "A", <>, <>, "A"]
A & B) and our formula does not support those kinds of test cases.The question is now how do we handle when more than 1 task ties for the most frequent task? Well, we know that if more than 1 task ties for the most frequent task, it doesn't matter which one we choose, any of them will force the same structure sequence.We also know from deriving the formula that we take t and then subtract one to get t - 1, then multiply by n + 1 to build blocks that make up the forced sequence. Finally, we attach the extra task we subtracted via t - 1 at the end to form a "tail" to the blocks.That approach works for tasks that only have 1 most frequent task, but when multiple tasks tie for the most frequent task, the "tail" is the size of how many tasks tie for the most frequent task.With this in mind, let's re-do our formula:Minimum steps formula v2
Where:
The count of the most frequent CPU task
The cooling interval (minimum tasks between duplicates)
The count of tasks that tie for the most frequent task
python
1class Solution:2 def leastInterval(self, tasks: List[str], n: int) -> int:3 freq = {}4 t = 05 c = 06 7 # building a frequency map of tasks8 # and counting how many tasks tie for the most frequent task9 for task in tasks:10 freq[task] = freq.get(task, 0) + 111
12 if freq[task] > t:13 t = freq[task]14 c = 115 elif freq[task] == t:16 c += 117 18 return (t - 1) * (n + 1) + ctest case 3
input: tasks = ["A", "C", "A", "B", "D", "B"], n = 1
output: 6
output: 6
(t - 1) * (n + 1) + c we would get (2 - 1) * (1 + 1) + 2 = 4 which is obviously wrong because our expected output is 6.Let's draw out one possible solution sequence:test case 3 solution sequence
["A", "C", "A", "B", "D", "B"]
python
1class Solution:2 def leastInterval(self, tasks: List[str], n: int) -> int:3 freq = {}4 t = 05 c = 06 7 # building a frequency map of tasks8 # and counting how many tasks tie for the most frequent task9 for task in tasks:10 freq[task] = freq.get(task, 0) + 111
12 if freq[task] > t:13 t = freq[task]14 c = 115 elif freq[task] == t:16 c += 117 18 # if our formula underestimates, the min time to execute19 # all tasks is the amount of tasks!20 return max((t - 1) * (n + 1) + c, len(tasks))