Scheduling & Interval Partitioning
Three classic scheduling problems all yield to greedy algorithms — and all three turn on a single design decision: which key to sort by. Interval scheduling sorts by finish time to pack the most compatible jobs; interval partitioning sorts by start time and proves the rooms needed equal the maximum overlap depth; minimizing maximum lateness sorts by deadline and is justified by an adjacent-swap exchange argument.
╌╌╌╌
The previous lesson introduced the greedy method on its canonical example: activity selection, where we pick a maximum-size set of mutually compatible intervals by repeatedly taking the one that finishes earliest. That was a single problem solved by a single sort key. This lesson covers the whole family of interval and scheduling problems that the greedy method solves; they are nearly the same algorithm with different sort keys. Sort by finish time to maximize how many jobs fit; by start time to minimize how many machines you need; by deadline to minimize how late the worst job runs. Choosing the key correctly, and proving that choice optimal, is the entire problem.
Interval scheduling, recapped
Recall the setup. We are given intervals, interval being the half-open , and two intervals are compatible when they do not overlap. We want a maximum-size set of pairwise compatible intervals, the most jobs we can run on one machine without conflict.1
The greedy rule, proved correct last lesson, is earliest finish time first: sort by , take the first interval, discard everything that overlaps it, and recurse on the rest. The selection itself is one linear scan, so after the sort the algorithm runs in .
Greedy never falls behind: pick the earliest-finishing interval each round, and greedy's -th choice frees the machine no later than any rival schedule's -th, so it always has at least as much room left.
For example, take five requests for one machine, already sorted by finish time:
| Interval | |||||
|---|---|---|---|---|---|
| finish | 4 | 5 | 6 | 7 | 8 |
Scanning in finish order and keeping , the finish of the most recently accepted interval:
| Step | Interval | before | ? | Action | |
|---|---|---|---|---|---|
| 1 | — | — | accept, | ||
| 2 | ? no | reject | |||
| 3 | ? no | reject | |||
| 4 | ? yes | accept, | |||
| 5 | ? no | reject |
Greedy accepts , a maximum set of two: no three of these five intervals are pairwise compatible, since alone overlaps every other, and share the point . The rule discards and the moment they overlap the last acceptance, and never revisits them.
The output is a maximum-size set of mutually compatible intervals, computed in . Everything below reuses this skeleton (sort, scan, exchange-argument proof) with a different key and a different objective.
Interval partitioning: minimize the rooms
Now flip the question. Instead of dropping intervals to fit on one machine, we keep all of them and ask for the fewest machines (rooms, colors, frequencies) needed to run them, where two intervals sharing a machine must be compatible. Phrased as graph coloring: color the intervals so that any two overlapping intervals get different colors, using the minimum number of colors.2
The right invariant is depth. Define the depth at a point as the number of intervals containing , and let be the maximum over all points. Depth is a hard lower bound on rooms, and greedy matches it.
The greedy algorithm sorts by start time and keeps a min-heap of machines keyed by the time each becomes free. For each interval in start order, if the machine that frees earliest is already free by this interval's start, reuse it; otherwise open a new machine.
- 1sort by start time ascending
- 2empty min-heap of machines keyed by free time
- 3for each interval in start order do
- 4if nonempty and then
- 5reuse earliest-freed machine
- 6else
- 7new machinenone free: open one
- 8
- 9
- 10returntotal machines opened
We trace the scan. Intervals enter in start order; each reuses the machine that frees earliest if it is already free, otherwise it opens a new one. The third interval arrives while both open machines are still busy, so it forces a third; that instant is a point of depth , the witness for the lower bound.
The min-heap is what makes each step cheap: it holds one entry per open machine, keyed by the time that machine next frees, so the earliest-freeing machine is always at the root. Walking the six intervals through it shows the heap state at each step. Each row lists the arriving interval, the root's free time, whether that machine can be reused, and the heap after the step.
| Interval | root free time | reuse? | machines | heap after (free times) | |
|---|---|---|---|---|---|
| — (empty) | open R1 | 1 | |||
| ? no, open R2 | 2 | ||||
| ? no, open R3 | 3 | ||||
| ? yes, reuse R1 | 3 | ||||
| ? yes, reuse R2 | 3 | ||||
| ? yes, reuse R3 | 3 |
The machine count climbs to over the first three intervals — precisely the depth- overlap of , , — and every later interval finds a freed machine at the root, so the count never rises again. The answer is , matching .
Because we processed intervals in start order, no interval we open a machine for overlaps a future interval that already passed, so the depth witness is real, not an artifact of order. The sort is and each interval does heap work, for overall.3 This is exactly LeetCode's Meeting Rooms II and Minimum Number of Arrows in disguise: the first asks for directly; the second asks for the complementary count of points that stab all intervals.
Minimizing maximum lateness
The third problem changes the objective from count to timing. We have one machine and jobs; job needs units of processing and has a deadline . We must order the jobs (the machine runs one at a time, no preemption); if job finishes at time its lateness is , and we want to minimize the maximum lateness across all jobs.1
The greedy rule is earliest deadline first (EDF): ignore the processing times entirely, sort the jobs by deadline , and run them back-to-back in that order with no idle gaps. The proof uses both qualifiers: no idle time and deadline order.
- 1sort jobs so thatearliest deadline first
- 2running finish time, no idle gaps
- 3worst lateness so far
- 4for to do
- 5job finishes here
- 6update max lateness
- 7return order with lateness
So minimizing maximum lateness is, again, sort-and-scan: sort by deadline in , run in that order, done. In a worked run, with the jobs in deadline order, each finish time falls out of the running total, and the lateness of the worst job is what we report.
Here jobs (length , deadline ), (length , deadline ), and (length , deadline ) run in deadline order . Finish times are the running sums , , ; latenesses are , , , so . To see that no order does better, try the intuitive shortest-job-first order : now finishes at (lateness ), at (lateness ), and at (lateness ), giving — three times worse. Sorting by length optimized the wrong thing; only the deadline order controls the worst lateness, exactly what the adjacent-swap argument guarantees.
The trio, and the one decision
These three — interval scheduling, interval partitioning, and maximum lateness — are the canonical greedy-on-intervals trio. They share a single shape: sort the intervals or jobs by one key, then make one pass. Everything distinctive about each lives in the key:
| Problem | Objective | Sort key | Optimality proof |
|---|---|---|---|
| Scheduling | max compatible jobs | finish time | stays-ahead / exchange |
| Partitioning | min machines | start time | depth lower bound = greedy |
| Max lateness | min worst lateness | deadline | adjacent-swap exchange |
The lesson is that for greedy interval problems the design work is almost entirely choosing the sort key, and the verification work is a short exchange or stays-ahead argument confirming the choice. Get the key right and the rest is a linear scan.
Weights, online arrivals, and where greedy stops
The three interval problems above all yield to a single sort. Two natural generalizations break the greedy rule, and the boundary is instructive.
Weighted interval scheduling. Give each interval a weight and ask for the maximum-weight compatible subset, not the maximum-count one. Earliest-finish greedy now fails: a single high-weight interval can be worth more than many cheap ones that would displace it. To address this, use dynamic programming. Sort by finish time, precompute for each interval the largest index of an interval that ends at or before starts, and set — take (and jump to the last compatible predecessor) or skip it. The recurrence runs in and is the canonical example that the unweighted problem is greedy while the weighted one is DP.4 It is the same failure as fractional versus 0/1 knapsack: weights destroy the greedy-choice property.
Online interval scheduling. When intervals arrive one at a time and each must be accepted or rejected on the spot — a machine-reservation feed, say — no deterministic online algorithm can be competitive against the offline optimum in the worst case: an adversary reveals a short interval, and whether you take it or not it can follow with intervals that make the other choice far better, forcing an unbounded competitive ratio for arbitrary lengths.5 Restricting interval lengths or admitting randomization restores bounded ratios, which is why real reservation systems either batch requests (recovering the offline sort) or accept a provable approximation. The greedy of this lesson depends on seeing the whole instance at once.
Takeaways
- Interval scheduling maximizes compatible jobs by earliest finish first; a stays-ahead exchange argument proves optimality, in .
- Interval partitioning minimizes machines by earliest start first with a min-heap of free times; the answer equals the maximum depth , since depth forces machines and greedy never opens more.
- Minimizing maximum lateness on one machine uses earliest deadline first; an adjacent-swap exchange argument shows removing inversions never raises .
- All three are the same sort-then-scan skeleton: the entire design decision is the sort key (finish, start, or deadline), and the proof is a short exchange argument.
Footnotes
- CLRS, Ch. 16 — Greedy Algorithms (§16.1): activity selection by earliest finish time and the structure of single-machine scheduling. ↩ ↩2
- Skiena, § — Scheduling: interval partitioning / coloring and the equivalence of minimum machines with maximum overlap depth. ↩
- Erickson, Ch. — Greedy Algorithms: greedy scheduling proofs by exchange arguments and the sort-key-is-the-algorithm framing. ↩
- Kleinberg, J. & Tardos, É. (2005), Algorithm Design, Ch. 6 — Dynamic Programming (§6.1): weighted interval scheduling solved by the recurrence, the standard example that adding weights turns a greedy problem into a DP one. ↩
- Borodin, A. & El-Yaniv, R. (1998), Online Computation and Competitive Analysis, Cambridge University Press — the competitive-analysis framework and lower bounds showing deterministic online interval scheduling has no bounded competitive ratio for arbitrary interval lengths. ↩
╌╌ END ╌╌