Task Scheduler
MediumThe problem
Each letter in tasks is a job that takes 1 time unit. The CPU can do one job per unit or sit idle. Two jobs with the same letter must have at least n units between them. Return the fewest time units needed to finish all jobs; jobs may be done in any order.
- Example 1Input: tasks = ["A","A","A","B","B","B"], n = 2Output: 8
One schedule is A B idle A B idle A B.
- Example 2Input: tasks = ["A","A","A","B","B","B"], n = 0Output: 6
With no waiting required, every unit does a job.
- Example 3Input: tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2Output: 16
The six As need gaps of two units, for example A B C A D E A F G A idle idle A idle idle A.
- 1 ≤ tasks.length ≤ 10,000
- Tasks are uppercase letters A to Z
- 0 ≤ n ≤ 100
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
Always do the task with the most remaining runs, but a task must cool down for n intervals after running.
The idea
Max-heap of counts plus a queue of (count, time it becomes available again). Each tick run the top task, push it into the cooldown queue, release finished cooldowns. (Math shortcut: (maxCount−1)·(n+1) + number of tasks with maxCount.)
Target: O(T log 26) time
Go function shape
func leastInterval(tasks []byte, n int) intReference solution
Tested with go test. Try it yourself first, then compare.
// LeastInterval: the most frequent task decides the length. Place it every n+1 slots; the other tasks fill the gaps.
// Frames: (maxCount-1) full frames of n+1 slots, plus a last partial row holding every task tied for the max.
// If there are so many tasks that no idle time is needed, the answer is simply len(tasks).
func LeastInterval(tasks []byte, n int) int {
var counts [26]int
maxCount := 0
for _, t := range tasks {
counts[t-'A']++
maxCount = max(maxCount, counts[t-'A'])
}
tied := 0
for _, c := range counts {
if c == maxCount {
tied++
}
}
return max(len(tasks), (maxCount-1)*(n+1)+tied)
}