Non-overlapping Intervals

medium

Given an array of intervals where intervals[i] = [start, end], return the minimum number of intervals you must remove so that the remaining intervals are non-overlapping.

Two intervals that only touch at an endpoint (e.g. [1, 2] and [2, 3]) are considered non-overlapping.

Hints

Removing the fewest intervals is the same as keeping the most non-overlapping ones.
That's activity selection — sort by end time and greedily keep compatible intervals.
Since touching is allowed, keep an interval when its start is >= the last kept end.

Common doubts

Every interval is either kept or removed, so removals = n - kept. Maximizing kept minimizes removals.
When two intervals overlap you should drop the one that ends later (it blocks more of the timeline). Sorting by end makes the greedy keep the earlier-ending one automatically.
Intervals that merely touch at an endpoint don't overlap, so an interval starting exactly at the last kept end is still compatible.

Interview follow-ups

Greedy no longer applies; it becomes weighted interval scheduling — sort by end and DP with binary search for the last compatible interval.
Track, during the greedy, the intervals you drop; those are exactly the ones to remove.

Fun facts

  • This is activity selection wearing a disguise — the 'remove the fewest' framing is just the complement of the classic 'select the most'.
  • The same earliest-end greedy underlies interval graph coloring and conflict-free scheduling.

Asked at

AmazonGoogleMicrosoftMeta
Frequently Sometimes Occasionally
Example 1
Input: intervals = [[1,2],[2,3],[3,4],[1,3]]
Output: 1
Remove [1,3] and the remaining intervals are non-overlapping.
Example 2
Input: intervals = [[1,2],[1,2],[1,2]]
Output: 2
Keep one [1,2] and remove the other two.
Constraints

- 1 <= intervals.length <= 10^5 - intervals[i] == [start_i, end_i] - -5 * 10^4 <= start_i < end_i <= 5 * 10^4

Solve this problem →