Non-overlapping Intervals
Given an array of intervals where intervalsi = [start_i, end_i], return the minimum number of intervals you need to remove so the rest do not overlap. Sort the intervals by their end time , then sweep once, keeping any interval that starts at or after the end of the last interval you kept. Whatever is not kept must be removed.
Constraints
- 1 ≤ intervals.length ≤ 105
- intervalsi.length == 2
- -5 × 104 ≤ start_i < end_i ≤ 5 × 104
Example
intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]1Explanation Removing [1, 3] leaves [1, 2], [2, 3], [3, 4], which do not overlap.
In plain terms
- Interval
- A range with a start and an end, like [1, 3] meaning "from 1 to 3".
Sweep intervals sorted by end time, keeping what fits
Sorted by end: [1,2] is kept first. lastEnd becomes 2, kept=1.
What happens in this step
sorted (by end): [1,2], [2,3], [1,3], [3,4] lastEnd = sorted[0][1] = 2, kept = 1 The first interval after sorting is always kept — it seeds the running lastEnd.
Steps to visualize
- Sort the intervals by their end value.
- Keep the first interval and remember its end as lastEnd.
- For each following interval, keep it only if its start is at or after lastEnd, and update lastEnd.
- Any interval that overlaps the last one kept must be removed.
- The answer is the total count minus how many were kept.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
Sorted by end: [1,2] is kept first. lastEnd becomes 2, kept=1.
What happens in this step
sorted (by end): [1,2], [2,3], [1,3], [3,4] lastEnd = sorted[0][1] = 2, kept = 1 The first interval after sorting is always kept — it seeds the running lastEnd.
Solution
function eraseOverlapIntervals(intervals) {
if (intervals.length === 0) return 0;
const sorted = [...intervals].sort((a, b) => a[1] - b[1]);
let lastEnd = sorted[0][1];
let kept = 1;
for (let i = 1; i < sorted.length; i++) {
const [start, end] = sorted[i];
if (start >= lastEnd) {
kept++;
lastEnd = end;
}
}
return intervals.length - kept;
}- Time
- O(n log n)
- Space
- O(n)
Test cases
| Input | Expected | Covers |
|---|---|---|
intervals = [[1, 2], [2, 3], [3, 4], [1, 3]] | 1 | example from the docstring |
intervals = [[1, 2], [1, 2], [1, 2]] | 2 | every interval is identical, only one can be kept |
intervals = [[1, 2], [2, 3]] | 0 | touching but not overlapping intervals, nothing to remove |
intervals = [[1, 2]] | 0 | smallest valid input, a single interval |
intervals = [[1, 10], [2, 3], [4, 5], [6, 7]] | 1 | one large interval overlapping several small ones |
intervals = [[1, 2], [3, 4], [5, 6]] | 0 | a larger set with no overlaps at all |