The O(n) Club: Task Scheduler Idle Madness (and the Math That Saves You)
⚡ TL;DR
Given a list of tasks and a cooldown period, schedule them so you don’t have to see the same annoying letter less than
n
times apart—while also keeping your CPU from excessive napping. Forget simulating every tick: just crunch the counts. Here’s the hero snippet:// Greedy math, not caffeine-fueled simulation tasks = [A,A,A,B,B,B], n = 2 int minIntervals = Math.max(tasks.length, (maxFreq-1)*(n+1)+numMaxFreqTasks);
🧠 How Devs Usually Mess This Up
First, everyone assumes their CPU is that over-it intern: idling at every possible moment. So you build a max heap, painstakingly pop the next available task, and track cooldowns like you’re managing the world’s least-fun amusement park. Next thing? Burned-out brain cells and a lovingly crafted Time Limit Exceeded on LeetCode. It’s all so unnecessary if you trust math more than brute force—and yes, you really should.
🔍 What’s Actually Going On
Picture a party where your most popular friends keep hogging the aux, but party rules say they must take a break between bangers. If you have enough wallflowers mingling in between, the jams stay non-stop. If the guest list is small, the music pauses (idle slots) until the DJ’s allowed back. The scheduling problem’s villain? The task that repeats the most. Your job: spread them out, fill the gaps if you can, and only leave the CPU idle when there’s truly nothing else to do.
🛠️ PseudoCode
- Count frequency of each task (they’re A-Z, keep it simple):
int[] freq = new int[26]; for (char t : tasks) freq[t - 'A']++;
(Now you know who the party animals are.)
- Find the highest frequency and count how many times it’s tied:
int maxFreq = 0, numMax = 0; for (int f : freq) { if (f > maxFreq) { maxFreq = f; numMax = 1; } else if (f == maxFreq && f > 0) { numMax++; } }
(If three friends tie for most annoying, you need extra idle just for them!)
- Math it up:
int minIntervals = Math.max(tasks.length, (maxFreq - 1) * (n + 1) + numMax);
(If you can fill every slot, no idle. Else, bring on the awkward pauses.)
- Return
minIntervals
— and enjoy that O(n) smugness.
💻 The Code
public int leastInterval(char[] tasks, int n) {
int[] freq = new int[26];
for (char t : tasks) freq[t - 'A']++;
int maxFreq = 0, numMax = 0;
for (int f : freq) {
if (f > maxFreq) {
maxFreq = f;
numMax = 1;
} else if (f == maxFreq && f > 0) {
numMax++;
}
}
return Math.max(tasks.length, (maxFreq - 1) * (n + 1) + numMax);
}
⚠️ Pitfalls, Traps & Runtime Smacks
- Every task is unique? Congrats: the CPU never idles. (Perfect party, zero wallflowers left behind.)
- All tasks the same? Hope the CPU likes naps: you’ll have tons of idle time.
- n = 0? The rules are gone, stack the tasks however you want.
- Complexity: O(tasks.length) time, O(1) space—thank you, 26 letters.
🧠 Interviewer Brain-Tattoo
“If you get the counts right, you never have to simulate a single sad idle tick. Math > MaxHeap every day.”