Remove the Fewest Overlapping Intervals
TikTokSoftware Engineer · OnsiteLast updated
Tests greedy interval scheduling and sorting techniques to find the minimum number of intervals to remove so that no remaining intervals overlap.
Problem Statement
You are given an array of intervals intervals where intervals[i] = [start_i, end_i]. Each interval represents a range on a 1D coordinate line.
Two intervals [a, b] and [c, d] (with a <= c) overlap if c < b. Intervals that touch at a single point (e.g., b == c) do not overlap.
Return the minimum number of intervals you must remove so that the remaining intervals are mutually non-overlapping.
Function Signature
def erase_overlap_intervals(intervals: list[list[int]]) -> int:
pass
Constraints
1 <= len(intervals) <= 2 * 10^5intervals[i].length == 2-10^9 <= start_i < end_i <= 10^9- The input may contain duplicate intervals (i.e., identical
[start, end]pairs).
Examples
Example 1:
Input: intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]
Output: 1
Explanation: [1, 3] can be removed and the remaining intervals [[1, 2], [2, 3], [3, 4]] are non-overlapping.
Example 2:
Input: intervals = [[1, 2], [1, 2], [1, 2]]
Output: 2
Explanation: You need to remove two [1, 2] intervals so that the remaining [1, 2] has no duplicate overlaps.
Example 3:
Input: intervals = [[-50, -20], [-30, 10], [-20, 0], [0, 50]]
Output: 1
Explanation: Removing [-30, 10] leaves [[-50, -20], [-20, 0], [0, 50]], where touching endpoints (like -20 and 0) do not count as overlaps.
Edge Cases to Consider
- All intervals are mutually disjoint: output should be
0. - All intervals are identical: output should be
len(intervals) - 1. - Completely nested intervals (e.g.,
[[1, 10], [2, 3]]): prioritize keeping the one with the earlier end time.
Hints
Hint 1
Minimizing the number of removed intervals is equivalent to maximizing the number of mutually non-overlapping intervals you keep.
Hint 2
Sort the intervals by their end points in ascending order to make a locally optimal choice at each step.
Hint 3
Iterate through the sorted intervals: keep the current interval if its start coordinate is greater than or equal to the end coordinate of the last kept interval; otherwise, increment your removal count.
Follow-up questions
- What changes if each interval also has an associated weight/cost, and you want to minimize total weight removed?
- How would you return the indices of the actual intervals removed, ensuring the lexicographically smallest list of indices in case of ties?
- If interval endpoints are continuously streamed in real-time, how would you maintain the maximum non-overlapping set dynamically?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.