Merge Intervals
MediumThe problem
You get a list of ranges [start, end] in any order. Combine every group of overlapping ranges into one and return the result sorted by start. Ranges that only touch at one point count as overlapping.
- Example 1Input: intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]Output: [[1, 6], [8, 10], [15, 18]]
[1, 3] and [2, 6] overlap, so they merge into [1, 6].
- Example 2Input: intervals = [[1, 4], [4, 5]]Output: [[1, 5]]
They touch at 4, which counts as overlapping.
- Example 3Input: intervals = [[8, 10], [1, 2], [2, 3]]Output: [[1, 3], [8, 10]]
The input is not sorted. [1, 2] and [2, 3] touch at 2.
- 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
If the list is sorted by start, an interval can only overlap the one just before it.
The idea
Sort by start. Keep a result list; if the current start ≤ last end, extend last end with max; else append.
Target: O(n log n) time
Go function shape
func merge(intervals [][]int) [][]intReference solution
Tested with go test. Try it yourself first, then compare.
// Merge: merge all overlapping intervals.
func Merge(intervals [][]int) [][]int {
sorted := slices.Clone(intervals)
slices.SortFunc(sorted, func(a, b []int) int { return cmp.Compare(a[0], b[0]) })
out := [][]int{}
for _, cur := range sorted {
last := len(out) - 1
if last < 0 || out[last][1] < cur[0] { // gap: no overlap
out = append(out, []int{cur[0], cur[1]})
} else { // overlap (touching counts): extend the end
out[last][1] = max(out[last][1], cur[1])
}
}
return out
}