Rearrange Tasks With Cooldown
Company: Google
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates task-scheduling and constraint-handling skills, testing algorithmic reasoning about arranging repeated jobs with cooldown constraints along with analysis of schedule optimality and algorithmic complexity.
Part 1: Shortest Cooldown Schedule With Idles
Constraints
- 0 <= len(tasks) <= 100000
- 0 <= cooldown <= 100000
- Each element of `tasks` is a single uppercase English letter from 'A' to 'Z'
Examples
Input: (['A', 'A', 'A', 'B', 'B', 'C'], 2)
Expected Output: 'ABCAB_A'
Explanation: Using the required tie-break, the greedy shortest schedule is ABCAB_A.
Input: (['A', 'A', 'A', 'B'], 2)
Expected Output: 'AB_A__A'
Explanation: After using A and B, the scheduler must insert idles until A becomes available again.
Input: (['A', 'A', 'B', 'B'], 2)
Expected Output: 'AB_AB'
Explanation: One idle is necessary between the second A and second B.
Input: ([], 3)
Expected Output: ''
Explanation: No tasks means an empty schedule.
Input: (['B', 'A', 'A'], 0)
Expected Output: 'AAB'
Explanation: With cooldown 0, tasks may repeat immediately. The deterministic rule picks A first.
Hints
- Keep available tasks in a max-heap keyed by remaining count, and store recently used tasks in a queue with the time when they become available again.
- If the heap is empty but some tasks are still cooling down, you must place an idle slot.
Part 2: Cooldown Permutation Without Idles
Constraints
- 0 <= len(tasks) <= 100000
- 0 <= cooldown <= 100000
- Each element of `tasks` is a single uppercase English letter from 'A' to 'Z'
Examples
Input: (['A', 'A', 'B', 'B', 'C', 'C'], 2)
Expected Output: 'ABCABC'
Explanation: The tasks can be perfectly interleaved with distance 2.
Input: (['A', 'A', 'A', 'B', 'B', 'C'], 2)
Expected Output: ''
Explanation: A valid permutation without idles does not exist.
Input: (['A', 'A', 'B', 'C'], 2)
Expected Output: 'ABCA'
Explanation: A appears at positions 0 and 3, which satisfies cooldown 2.
Input: ([], 2)
Expected Output: ''
Explanation: The empty input has the empty permutation.
Input: (['B', 'A', 'A'], 0)
Expected Output: 'AAB'
Explanation: With cooldown 0, adjacent equal tasks are allowed.
Hints
- This is similar to Part 1, except you are not allowed to insert idle slots when nothing is available.
- If the available-task heap becomes empty before you place all tasks, then no valid permutation exists.
Part 3: Validate That a Cooldown Schedule Is Minimal
Constraints
- 0 <= len(tasks) <= 100000
- 0 <= cooldown <= 100000
- 0 <= len(schedule) <= 200000
- Each element of `tasks` is a single uppercase English letter from 'A' to 'Z'
Examples
Input: (['A', 'A', 'A', 'B', 'B', 'C'], 2, 'ABCAB_A')
Expected Output: True
Explanation: The schedule is valid and its length 7 is the minimum possible.
Input: (['A', 'A', 'B'], 1, 'A_BA')
Expected Output: False
Explanation: The schedule is valid but not minimal; 'ABA' is shorter.
Input: (['A', 'A', 'B'], 1, 'AAB')
Expected Output: False
Explanation: The two A tasks are too close together.
Input: ([], 2, '')
Expected Output: True
Explanation: The empty schedule is valid and minimal for empty input.
Input: (['A', 'B'], 0, 'AA')
Expected Output: False
Explanation: The multiset of tasks does not match the input.
Hints
- First check correctness of the candidate schedule: task counts must match exactly, and repeated letters must be far enough apart.
- A lower bound on the shortest possible length comes from the most frequent task types. Compare the schedule length against that bound.
Part 4: Count Heap and Cooldown Operations
Constraints
- 0 <= len(tasks) <= 100000
- 0 <= cooldown <= 100000
- Each element of `tasks` is a single uppercase English letter from 'A' to 'Z'
Examples
Input: (['A', 'A', 'A', 'B', 'B', 'C'], 2)
Expected Output: [6, 6, 2]
Explanation: There are 6 total heap pushes, 6 heap pops, and the cooldown queue peaks at size 2.
Input: ([], 3)
Expected Output: [0, 0, 0]
Explanation: No tasks means no heap or queue activity.
Input: (['A'], 5)
Expected Output: [1, 1, 0]
Explanation: One initial heap insertion and one pop; nothing waits in cooldown.
Input: (['A', 'A', 'B', 'B', 'C', 'C'], 2)
Expected Output: [6, 6, 3]
Explanation: After scheduling A, B, and C once, all three task types are cooling down at the same time.
Input: (['B', 'A', 'A'], 0)
Expected Output: [3, 3, 1]
Explanation: The second A returns immediately on the next slot, and the cooldown queue never exceeds size 1.
Hints
- Simulate the scheduler exactly. Count heap pushes both when you build the initial heap and when cooled-down tasks return.
- The cooldown queue size changes only when you execute a task with remaining copies or when tasks become available again.