Non-overlapping Intervals
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.
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.
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.
An array intervals where intervals[i] = [start_i, end_i].
One integer: the minimum number of intervals to remove.
Remove [1,3]. The rest, [1,2], [2,3], [3,4], only touch each other.
All three are the same interval, so only one of them can stay.
They only touch at 2, so they already don't overlap.
- β’ 1 β€ intervals.length β€ 10^5
- β’ intervals[i].length == 2
- β’ β5 Β· 10^4 β€ start_i < end_i β€ 5 Β· 10^4
First, think yourself
Before opening any solution, try to answer these on paper. Use hints only when stuck β each hint is counted.
- 1.
Removing the fewest is the same as keeping the most. Which of the two is easier to think about?
- 2.
If two intervals overlap, at least one of them has to go. Which one would you rather keep?
- 3.
Does a long interval help you or hurt you when you want to keep many?
- 4.
What does it mean for the next interval if the one you kept finishes early?
- 5.
Is it more useful to sort by start time or by end time here?
Brute force approach
Better approach
Optimized approach
Why does this algorithm work?
Dry run
All approaches compared
| Approach | Idea | Time | Space |
|---|---|---|---|
| Brute Force | Try keeping or removing each interval, and take the largest set without overlaps | O(2^N) | O(N) |
| Better | dp[i] = most intervals kept if interval i is the last one; check every earlier j | O(NΒ²) | O(N) |
| Optimal | Sort by end; keep an interval when it starts at or after the last kept end | O(N log N) | O(1) |
Why does this belong to this pattern?
- β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 `>`.
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.
Don't make this mistake
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.)
[1,2] and [2,3] do not overlap in this problem. With >, example 1 would remove 2 intervals instead of 1.
Starts can be negative (down to β5Β·10^4). With lastEnd = 0, an interval like [-5, -1] would wrongly look like it overlaps.
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.
Want to implement this?
Write it yourself on LeetCode, then come back and compare your code with the solutions above.
Open coding workspaceHow this concept connects to System Design & C++ Systems
Top engineering interviews test whether you understand how algorithms like Intervals translate into production architectures and low-level memory mechanics.
Foundations: Object-Oriented Principles in C++23
Class invariants, pure virtual interfaces, and RAII smart pointers.
Food Delivery System (Zomato Architecture)
Real-world machine coding application of algorithms and design patterns.
Pointers vs References Deep Dive
Pointer arithmetic and memory layout under the hood.
Virtual Method Table (vtable) & Memory Layout
Polymorphism, vptr overhead, and multiple inheritance in memory.