◀ THE GRIND — HEAP / PRIORITY QUEUE

Task Scheduler

MEDIUM✓ CHIP-TIMEDLC #621 — FULL STATEMENT ↗

The drill: CPU tasks each need a cooldown of n idle-or-other-task slots before the same task letter can run again — schedule everything (idle ticks allowed) and report the fewest total time units needed.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A list of CPU tasks arrives, each labeled with a letter, along with a cooldown n — once a given task letter runs, that same letter can't run again until n other slots, idle or otherwise, have passed.

Every unit of time either runs exactly one task or sits idle, and idle time still counts toward the total — the schedule has to cover every task in the list, in any order that respects the cooldown.

The answer is the fewest total time units needed to get every task done at least once, cooldowns and all.

EX 01
tasks = ["A", "A", "A", "B", "B", "B"] · n = 2
8
THE CLASSIC TWO-TASK SHAPE
EX 02
tasks = ["A", "A", "A", "B", "B", "B"] · n = 0
6
NO COOLDOWN AT ALL, JUST RUN EVERYTHING BACK TO BACK
EX 03
tasks = ["A", "A", "A", "A", "A", "A", "B", "C", "D", "E", "F", "G"] · n = 2
16
ONE DOMINANT TASK WITH PLENTY OF FILLERS
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

The task that shows up the most is the real bottleneck — it forces cooldown gaps that the rarer tasks may or may not be able to fill.

HINT 2 THE STRUCTURE

Picture rounds of length n+1: fill each round with whatever's most available right now, and only fall back to idle when literally nothing has finished its cooldown.

HINT 3 ONE STEP FROM THE ANSWER

A max-heap of remaining counts drives the picks; a cooldown queue holds tasks until their wait is up and hands them back to the heap exactly when they become eligible again.

COACH'S BOARD — THE PATTERN, STEP BY STEP
FILLING THE COOLDOWNPATTERN · MAX-HEAP + COOLDOWN QUEUEtasks = [A,A,A,B,B,B] · n = 2
STEP 1

A and B each appear 3 times, and a cooldown of n=2 means the same letter can't run again until 2 other slots pass.

STEP 1 / 9 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/task-scheduler.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def leastInterval(self, tasks: List[str], n: int) -> int:
        counts = collections.Counter(tasks)
        heap = [-c for c in counts.values()]
        heapq.heapify(heap)
        time = 0
        q = collections.deque()  # (releaseTime, remainingCountNegated)
        while heap or q:
            time += 1
            if heap:
                c = heapq.heappop(heap) + 1  # one unit done
                if c != 0:
                    q.append((time + n, c))
            if q and q[0][0] == time:
                heapq.heappush(heap, q.popleft()[1])
        return time
TIME O(TOTAL LOG 26)SPACE O(26)PYTHON · RACE PACE · 16 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED