Intervals: merge overlapping ranges
Intervals: merge overlapping ranges
You're given a list of intervals like [[1,3],[2,6],[8,10],[15,18]] and asked
to merge every pair that overlaps (LeetCode #56). Here [1,3] and [2,6]
touch, so they collapse into [1,6]; [8,10] and [15,18] stand alone. The
result is [[1,6],[8,10],[15,18]].
The unlock is to sort the intervals by their start. Once they're sorted, overlaps can only happen between an interval and the one most recently merged β you never have to look backwards. Walk the sorted list keeping a "current" merged interval; if the next one starts at or before the current end, stretch the end, otherwise close out the current interval and start a new one.
intervals.sort(key=lambda iv: iv[0])
merged = [intervals[0]]
for start, end in intervals[1:]:
if start <= merged[-1][1]: # overlaps the last merged interval
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
Note that touching counts as overlapping: [1,4] and [4,5] merge into
[1,5] because 4 <= 4.
Your task
Write merge(intervals) returning a list of [start, end] lists with all
overlaps merged, sorted by start. Return plain lists (not tuples). An empty
input gives an empty list.
merge([[1,3],[2,6],[8,10],[15,18]]) # [[1, 6], [8, 10], [15, 18]]
merge([[1,4],[4,5]]) # [[1, 5]] (touching merges)
merge([[1,4]]) # [[1, 4]]
merge([]) # []
Hint: sort first, then sweep once, growing the last merged interval whenever the next one starts at or before its end.
Tests
- two overlaps
- touching merges
- single interval
- empty input
- unsorted input (hidden)
- fully contained (hidden)
Stuck? Ask for a spark
$ Console output will appear here.