patternDSA/Merge Intervals
Core Pattern → Pattern 10

Merge Intervals

Sort by start time, sweep once. Overlap → extend. No overlap → push new. One sort, one pass — every interval problem solved.

Frequency:★★★★☆
·~35 min·Intermediate·7 problems
The Core Shock

Check every pair for overlap — O(n²). Sort once, sweep once — O(n log n)

Brute Force
O(n²) comparisons
n=1000: up to 500,000 pair checks
O(n²)
Sort + Sweep
One linear pass
Sort once O(n log n), then O(n) sweep
O(n log n)

The insight: sorting by start time means you only ever compare with the last merged interval. After sorting, any overlapping interval must start at or before the current interval's end — you never need to look further back. One sort, one pass.

Interval Problem Types

Three variants — each needs a slightly different approach.

Merge Overlapping

Sort by start. Sweep. Extend or push.

Unsorted list → non-overlapping merged list.
Merge IntervalsConflicting Appointments
Insert & Merge

3 phases: before / overlap / after.

Sorted list + new interval → updated list.
Insert Interval
Resources / Count

Min-heap of end times counts active slots.

How many rooms/CPUs needed simultaneously?
Min Meeting RoomsMax CPU LoadEmployee Free Time

The 3-Step Framework

The overlap condition and merge logic — memorize these cold.

01
Sort by Start Time

Always sort intervals by start time first (unless input guarantees sorted order). This makes overlap detection a single backward comparison.

intervals.sort(key=lambda x: x[0])
merged = [intervals[0]]
Sort is O(n log n) and dominates. The sweep is O(n). Forgetting to sort is the #1 bug.
02
Apply the Overlap Condition

Two intervals [a,b] and [c,d] overlap if c ≤ b. Merge to [a, max(b,d)]. Must use max — the new interval might be fully contained.

if start <= merged[-1][1]:           # overlap
    merged[-1][1] = max(merged[-1][1], end)
else:
    merged.append([start, end])
Use max(last_end, end). Without max, a contained interval [2,5] inside [1,10] would shrink the result to [1,5].
03
Use Heap for Resource Counting

Minimum meeting rooms and maximum CPU load need the earliest-ending active interval — that's a min-heap of end times. Sort by start, push end times, pop when intervals finish.

import heapq
rooms = []
for start, end in sorted(intervals):
    if rooms and rooms[0] <= start:
        heapq.heapreplace(rooms, end)
    else:
        heapq.heappush(rooms, end)
return len(rooms)
Heap size = active rooms right now. heapreplace = pop + push in one O(log n) call. Max heap size ever = answer.

Recognition

Interval problems are recognizable — look for these phrases.

Interval Pattern When
"Merge overlapping intervals"
"Insert a new interval"
"Find intersection of two interval lists"
"No two appointments conflict"
"Minimum rooms/machines needed"
"Maximum simultaneous load"
"Employee free time"
Input is list of [start, end] pairs
Use Heap Within Intervals When
"Minimum rooms" → min-heap of end times
"Maximum load" → track active tasks
"Employee free time" → sort all + sweep
Need earliest-finishing active interval
Multiple parallel resource streams
Sort-only misses simultaneous overlaps
Problem asks COUNT not merged list
Answer = max heap size during sweep