Sort ranges by their start, then walk through them once, comparing each with the previous one to see if they overlap.
Used for
current = [1,3]
start 2 <= end 3: end = max(3, 6) = 6
start 8 > end 6: new range
start 9 <= end 10: end = max(10, 12) = 12
The current range is [1,6] and the next one is [4,5]. What happens?
Not quite. [4,5] starts inside [1,6], so it overlaps, but max(6, 5) is still 6. The merged range stays [1,6].
Step 1 of 6
Goal: merge overlapping time ranges, like meetings. Sort them by start time first, so an overlap can only be with the range just before.
Step 2 of 6
Start with the first range, [1,3], as the current merged range.
Step 3 of 6
[2,6] starts at 2, before the current range ends (3), so they overlap. Stretch the end to the bigger of the two ends.
Step 4 of 6
[8,10] starts at 8, after the current end (6). There is a gap, so begin a new merged range.
Step 5 of 6
[9,12] starts at 9, before the current end (10): overlap. The end becomes 12. Result: [1,6] and [8,12]. Sorting is the slowest part, so O(n log n). This is the overlapping intervals pattern.
Step 6 of 6
Your turn.
function mergeIntervals(iv) { iv.sort((a, b) => a[0] - b[0]); const out = [iv[0]]; for (const [s, e] of iv.slice(1)) { const last = out.at(-1); s <= last[1] ? (last[1] = Math.max(last[1], e)) : out.push([s, e]); } return out;}