Non-overlapping Intervals
Greedy by earliest end — remove any interval that starts before the last kept end.
2 min read
intervals greedy sorting
Problem#
Return the minimum number of intervals to remove so the rest are non-overlapping.
Examples#
[[1,2],[2,3],[3,4],[1,3]]→1.[[1,2],[1,2],[1,2]]→2.
Constraints#
1 <= intervals.length <= 10^5.
Approach#
Sort by end. Sweep, keeping any interval whose start ≥ last kept end. Drop the rest.
Solution#
class Solution {public: int eraseOverlapIntervals(vector<vector<int>>& intervals) { sort(intervals.begin(), intervals.end(), [](auto& a, auto& b){ return a[1] < b[1]; }); int kept = 0, end = INT_MIN; for (auto& it : intervals) { if (it[0] >= end) { ++kept; end = it[1]; } } return intervals.size() - kept; }};import ( "math" "sort")
func eraseOverlapIntervals(intervals [][]int) int { sort.Slice(intervals, func(i, j int) bool { return intervals[i][1] < intervals[j][1] }) kept := 0 end := math.MinInt32 for _, it := range intervals { if it[0] >= end { kept++ end = it[1] } } return len(intervals) - kept}from typing import List
class Solution: def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: intervals.sort(key=lambda x: x[1]) kept = 0 end = float('-inf') for it in intervals: if it[0] >= end: kept += 1 end = it[1] return len(intervals) - keptfunction eraseOverlapIntervals(intervals) { intervals.sort((a, b) => a[1] - b[1]); let kept = 0; let end = -Infinity; for (const it of intervals) { if (it[0] >= end) { kept++; end = it[1]; } } return intervals.length - kept;}class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, (a, b) -> a[1] - b[1]); int kept = 0; int end = Integer.MIN_VALUE; for (int[] it : intervals) { if (it[0] >= end) { kept++; end = it[1]; } } return intervals.length - kept; }}function eraseOverlapIntervals(intervals: number[][]): number { intervals.sort((a, b) => a[1] - b[1]); let kept = 0; let end = -Infinity; for (const it of intervals) { if (it[0] >= end) { kept++; end = it[1]; } } return intervals.length - kept;}Editorial#
This is the classic interval scheduling problem. Sorting by end maximizes future flexibility: by keeping the interval that frees up the timeline soonest, we preserve the most room for subsequent intervals. The answer is total - kept.
Complexity#
- Time:
O(n log n). - Space:
O(1).
Concept revision#
Related#