Non-overlapping Intervals
MediumThe problem
You get a list of ranges [start, end]. Return the smallest number of ranges you must remove so that no two remaining ranges overlap. Ranges that only touch at one point, like [1, 2] and [2, 3], do not count as overlapping.
- Example 1Input: intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]Output: 1
Remove [1, 3]. What is left, [1, 2], [2, 3], [3, 4], only touches at the ends.
- Example 2Input: intervals = [[1, 2], [1, 2], [1, 2]]Output: 2
All three are identical and overlap each other, so only one can stay.
- Example 3Input: intervals = [[1, 2], [2, 3]]Output: 0
They only touch, so nothing needs to be removed.
- 1 ≤ len(intervals) ≤ 100,000
- start < end for every range
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
When two intervals overlap, which one is less harmful to keep?
The idea
Sort by end. Keep an interval if it starts at or after the last kept end; otherwise count a removal. (Keeping the earliest end leaves the most room.)
Target: O(n log n) time
Go function shape
func eraseOverlapIntervals(intervals [][]int) intReference solution
Tested with go test. Try it yourself first, then compare.
// EraseOverlapIntervals: fewest intervals to remove so the rest do not overlap.
// Greedy: sort by END, keep every interval that starts at or after the last kept end.
func EraseOverlapIntervals(intervals [][]int) int {
sorted := slices.Clone(intervals)
slices.SortFunc(sorted, func(a, b []int) int { return cmp.Compare(a[1], b[1]) })
kept, end := 0, 0
for i, iv := range sorted {
if i == 0 || iv[0] >= end {
kept++
end = iv[1]
}
}
return len(sorted) - kept
}