Given a characters array tasks, representing the tasks a CPU needs to do, where each letter represents a different task. Tasks can be done in any order. Each task takes one unit of time. For any unit of time, the CPU can either complete a task or be idle.
However, there is a non-negative integer n that represents the cooldown period between two same tasks (the same letter in the array). There must be at least n units of time between any two same tasks.
Return the minimum number of units of time the CPU will need to complete all the given tasks.
Input: tasks = ["A","A","A","B","B","B"], n = 2
Output: 8
Explanation:
A → B → idle → A → B → idle → A → B
Time units: 8
Input: tasks = ["A","A","A","B","B","B"], n = 0
Output: 6
Explanation: No cooldown needed
A → A → A → B → B → B
Input: tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
Output: 16
Explanation:
A → B → C → A → D → E → A → F → G → A → idle → idle → A → idle → idle → A
Greedy Strategy: Always execute the most frequent task first (to spread it out).
Key Insight: The limiting factor is the most frequent task!
If task A appears f times with cooldown n:
(f-1) * (n+1) + 1 time slotsApproach:
This is a Heap + Queue Simulation problem:
Time: O(n * tasks) in worst case, but typically much better
max_freq = frequency of most common task
max_count = number of tasks with max_freq
min_time = max(
len(tasks),
(max_freq - 1) * (n + 1) + max_count
)
This O(n) solution directly calculates answer!
Time: O(n * k) where k = unique tasks
Space: O(k)
1import java.util.*;
2
3class Solution {
4 public int leastInterval(char[] tasks, int n) {
5 // Count task frequencies
6 Map<Character, Integer> freq = new HashMap<>();
7 for (char task : tasks) {
8 freq.put(task, freq.getOrDefault(task, 0) + 1);
9 }
10
11 // Max-heap with frequencies
12 PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
13 maxHeap.addAll(freq.values());
14
15 // Queue stores [count, available_time] for tasks in cooldown
16 Queue<int[]> cooldownQueue = new LinkedList<>();
17
18 int time = 0;
19
20 while (!maxHeap.isEmpty() || !cooldownQueue.isEmpty()) {
21 time++;
22
23 if (!maxHeap.isEmpty()) {
24 // Execute most frequent task
25 int count = maxHeap.poll();
26 count--;
27
28 // If task has remaining executions, add to cooldown
29 if (count > 0) {
30 cooldownQueue.offer(new int[]{count, time + n});
31 }
32 }
33
34 // Check if any task cooldown expired
35 if (!cooldownQueue.isEmpty() && cooldownQueue.peek()[1] == time) {
36 maxHeap.offer(cooldownQueue.poll()[0]);
37 }
38 }
39
40 return time;
41 }
42}
43