Non-overlapping Intervals medium
Description
Given an array of intervals intervals where intervals[i] = [start, end], return the minimum number of intervals you need to remove to make the rest non-overlapping.
Examples
> Case 1:
intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]
Output: 1
# Remove [1, 3] — the remaining [1,2], [2,3], [3,4] don't overlap.
> Case 2:
intervals = [[1, 2], [1, 2], [1, 2]]
Output: 2
# Keep one, remove the other two.
> Case 3:
intervals = [[1, 2], [2, 3]]
Output: 0
# Already non-overlapping (touching at endpoints doesn't count).Constraints
1 <= intervals.length <= 10^5intervals[i].length == 2-5 · 10^4 <= start < end <= 5 · 10^4
Flip the question
“Minimum to remove” sounds tricky. Flip it: “maximum to keep”. If we can find the largest non-overlapping subset of size k, the answer is n − k.
That’s exactly Activity Selection from the classics page! Sort by end time, greedily pick non-overlapping intervals, count them.
The greedy
- Sort intervals by end time (ascending).
- Walk through. Keep the current interval if its start
>=last kept end. Otherwise, it overlaps — skip (= remove). - Return the count of skipped intervals.
Code
Touching endpoints don’t count as overlap. [1, 2] and [2, 3] are fine because 2 == 2 — neither is strictly inside the other. That’s why we use >= in the comparison, not >. If the problem statement says “even touching counts as overlap,” flip to strict >.
Why sort by end time?
Sorting by earliest end time maximizes the “room left” for the rest of the intervals. Counter-intuitively, sorting by start time or duration doesn’t work — see the introduction’s six-strategy comparison.
The exchange-argument proof: if an optimal solution picks an interval with a later end time when a non-overlapping interval with an earlier end time is available, swap them. The swap doesn’t create new overlaps (the earlier end leaves at least as much room) and the count is unchanged. Repeat until the optimum matches the greedy.
Sort by end, not by [start, end]
A common mistake: sorting by both start and end (the default tuple order). For this problem, sort only by end to maintain the invariant.
The interval family
Same template, slightly different per-step rules:
| Problem | Per-step rule |
|---|---|
| Non-overlapping Intervals (this one) | Skip if overlap; count skips. |
| Maximum Non-overlapping Intervals | Same algorithm; return kept count. |
| Min Arrows to Burst Balloons | Same algorithm; each “kept” interval = 1 arrow. |
| Maximum Length of Pair Chain | Like activity selection on pairs (a, b) where second < next first. |
| Course Schedule III | Greedy + max-heap (when greedy alone fails, swap out the longest course). |
All five are variations on the “sort by end, sweep” idea.
Edge case: empty input
if not intervals: return 0Strictly the constraints guarantee n >= 1, but defensive coding never hurts.
Analysis
- Time: O(n log n) — dominated by the sort.
- Space: O(1) extra.