2Brute2Best
πŸ”₯0

Non-overlapping Intervals

MediumΒ·LeetCode #435Basic Anchor
LeetCode
30-Second Mental ModelIntervals (coverage / removal) β€” greedy by end time
Complexity:O(2^N)β†’O(N log N)
Key Insight

Sort by end. Walk through the list with lastEnd = end of the last kept interval. If the next interval starts at or after lastEnd, keep it and move lastEnd to its end. Otherwise it overlaps the last kept one, so remove it. Answer = n βˆ’ kept.

Core Validity Invariant

An interval can be kept only if it starts at or after the end of the last kept one: start β‰₯ lastEnd. Touching (start == lastEnd) is fine.

01

Problem

You get a list of intervals, each written as [start, end].

Remove as few intervals as possible so that the ones left do not overlap each other. Return how many you removed.

Two intervals that only touch at one point, like [1, 2] and [2, 3], do not count as overlapping.

Input

An array intervals where intervals[i] = [start_i, end_i].

Output

One integer: the minimum number of intervals to remove.

Example 1
Input: intervals = [[1,2], [2,3], [3,4], [1,3]]
Output: 1

Remove [1,3]. The rest, [1,2], [2,3], [3,4], only touch each other.

Example 2
Input: intervals = [[1,2], [1,2], [1,2]]
Output: 2

All three are the same interval, so only one of them can stay.

Example 3
Input: intervals = [[1,2], [2,3]]
Output: 0

They only touch at 2, so they already don't overlap.

Constraints
  • β€’ 1 ≀ intervals.length ≀ 10^5
  • β€’ intervals[i].length == 2
  • β€’ βˆ’5 Β· 10^4 ≀ start_i < end_i ≀ 5 Β· 10^4
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck β€” each hint is counted.

  1. 1.

    Removing the fewest is the same as keeping the most. Which of the two is easier to think about?

  2. 2.

    If two intervals overlap, at least one of them has to go. Which one would you rather keep?

  3. 3.

    Does a long interval help you or hurt you when you want to keep many?

  4. 4.

    What does it mean for the next interval if the one you kept finishes early?

  5. 5.

    Is it more useful to sort by start time or by end time here?

03

Brute force approach

04

Better approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceTry keeping or removing each interval, and take the largest set without overlapsO(2^N)O(N)
Betterdp[i] = most intervals kept if interval i is the last one; check every earlier jO(NΒ²)O(N)
OptimalSort by end; keep an interval when it starts at or after the last kept endO(N log N)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • β€œremove the minimum number of intervals”Flip it: keep the maximum number of intervals that don't overlap.
  • β€œnon-overlapping”Kept intervals form a chain in time. Only the end of the last kept one matters.
  • β€œtouching is allowed”The test is `start β‰₯ lastEnd`, with `β‰₯`, not `>`.
Pick the most intervals+no two overlap+sort by end, keep the earliest finisher→Intervals (coverage / removal) — greedy by end time

This is the anchor of the coverage sub-pattern. The key choice is which end to sort by. Merge Intervals sorts by start because it glues overlaps together. Here we choose what to throw away, and the interval that ends first is always the safest one to keep. Burst Balloons uses the same greedy with one change: touching balloons share an arrow, so there it's start > arrow, not start β‰₯ lastEnd.

10

Don't make this mistake

Pattern confusion: sorting by start and keeping the first one
βœ— sort(intervals.begin(), intervals.end()); // by start if (iv[0] >= lastEnd) { kept++; lastEnd = iv[1]; }
βœ“ sort by end (a[1] < b[1]), then the same check

This looks like Merge Intervals, but it keeps whatever starts first. With [[1,10], [2,3], [4,5], [6,7]] it keeps [1,10] and removes the other 3. Sorting by end keeps 3 and removes only [1,10]. (If you do sort by start, you must also keep the one with the smaller end when two overlap.)

Treating touching intervals as overlapping
βœ— if (iv[0] > lastEnd) { ... }
βœ“ if (iv[0] >= lastEnd) { ... }

[1,2] and [2,3] do not overlap in this problem. With >, example 1 would remove 2 intervals instead of 1.

Starting lastEnd at 0
βœ— int lastEnd = 0;
βœ“ int lastEnd = INT_MIN;

Starts can be negative (down to βˆ’5Β·10^4). With lastEnd = 0, an interval like [-5, -1] would wrongly look like it overlaps.

Counting overlapping pairs

The answer is not the number of pairs that overlap. One long interval can overlap 5 others; removing just that one fixes all 5 pairs. Count what you keep, then subtract from n.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Intervals translate into production architectures and low-level memory mechanics.