Non-overlapping Intervals

MediumIntervals · Greedy🧩 Intervals & Line SweepLeetCode #435 ↗Updated

Problem

You are given a list of intervals [start, end]. Return the fewest intervals you must delete so that no two remaining intervals overlap. Intervals that only touch at an endpoint (e.g. [1,2] and [2,3]) do not count as overlapping.
Input[[1,2],[2,3],[3,4],[1,3]]Output1
Input[[1,2],[1,2],[1,2]]Output2
Input[[1,2],[2,3]]Output0

1 ≤ n ≤ 105  ·  -5·104 ≤ start < end ≤ 5·104

Try it yourself

Java
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Minimum removals = n − maximum number of intervals you can keep. To keep the most, always keep the interval that ends earliest — it leaves the most room for everything after it.
PatternIntervals & Line Sweep

Instinct See [start, end] pairs, meetings, bookings or the word "overlap"? Sort by an endpoint, then sweep left to right carrying one running fact.

Memory hack Sort, then sweep - start time to merge, end time to choose, +1/-1 events to count the crowd.

Open the Intervals & Line Sweep guide →

Approaches

Brute ForceRecursion: Keep or Skip Each Interval

Time O(2n)Space O(n)

Sort by start. For every interval try both choices: skip it, or keep it if it starts at or after the end of the last kept one. The best keep-count over all subsets gives the answer n − kept.

Java
public int eraseOverlapIntervals(int[][] intervals) {
    Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
    return intervals.length - maxKeep(intervals, 0, Integer.MIN_VALUE);
}
private int maxKeep(int[][] iv, int i, int prevEnd) {
    if (i == iv.length) return 0;
    int skip = maxKeep(iv, i + 1, prevEnd);
    if (iv[i][0] < prevEnd) return skip; // overlaps the last kept interval
    return Math.max(skip, 1 + maxKeep(iv, i + 1, iv[i][1]));
}

Explores every subset — correct, but exponential.

At a glance

LevelApproachTimeSpace
Brute ForceRecursion: Keep or Skip Each IntervalO(2n)O(n)
BetterDP (Longest Non-overlapping Chain)O(n2)O(n)
OptimalGreedy — Sort by EndO(n log n)O(1) excl. sort
Common pitfalls
  • Treating touching intervals as overlapping — use start < end, not ≤.
  • Sorting by start and always deleting the later interval — must drop the one ending later.
  • Comparator a[1] - b[1] can overflow for extreme values; use Integer.compare.
Interview tips
  • Reframe first: “remove fewest” = “keep the most non-overlapping”.
  • Justify earliest-end greedy with a one-line exchange argument.
  • Mention it is the same as Minimum Arrows to Burst Balloons (452).
Pattern
Interval scheduling (sort by end, greedy) → maximise compatible intervals or minimise deletions.
My notes saved in this browser