Advanced Interval Interview Patterns: Merge, Insert, Meeting Rooms, and Employee Free Time (2025)

Interval Problem Patterns

Interval problems form a distinct category: they involve ranges [start, end] and typically require detecting overlaps, merging, or scheduling. The canonical operations: sort by start time (almost always the first step), sweep line (process events in sorted order), and greedy scheduling (pick intervals that conflict least). Most medium/hard interval problems are variations of these core patterns. Key insight: two intervals [a, b] and [c, d] overlap if and only if a <= d AND c <= b.

Pattern 1: Merge Intervals (LC 56)

Given a list of intervals, merge all overlapping ones. Sort by start time. Iterate: if the current interval overlaps with the last merged interval (curr.start <= last.end), extend the last interval (last.end = max(last.end, curr.end)). Otherwise, add the current interval as a new entry.

def merge(intervals):
    intervals.sort(key=lambda x: x[0])
    merged = [intervals[0]]
    for start, end in intervals[1:]:
        if start <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], end)
        else:
            merged.append([start, end])
    return merged

Pattern 2: Insert Interval (LC 57)

Insert a new interval into a sorted, non-overlapping list. Three phases: (1) Add all intervals that end before new_interval starts. (2) Merge all intervals that overlap with new_interval (update new_interval’s start and end). (3) Add the merged interval and all remaining intervals.

def insert(intervals, new_interval):
    result = []
    i, n = 0, len(intervals)
    # Phase 1: no overlap, before new_interval
    while i < n and intervals[i][1] < new_interval[0]:
        result.append(intervals[i]); i += 1
    # Phase 2: overlapping intervals
    while i < n and intervals[i][0] <= new_interval[1]:
        new_interval[0] = min(new_interval[0], intervals[i][0])
        new_interval[1] = max(new_interval[1], intervals[i][1])
        i += 1
    result.append(new_interval)
    # Phase 3: remaining
    result.extend(intervals[i:])
    return result

Pattern 3: Meeting Rooms II (LC 253)

Minimum number of conference rooms to schedule all meetings. Two approaches: Sort start and end times separately. Use two pointers. If the next meeting starts before the earliest-ending meeting ends: need a new room. Else: reuse the room (advance end pointer).

def min_meeting_rooms(intervals):
    starts = sorted(i[0] for i in intervals)
    ends   = sorted(i[1] for i in intervals)
    rooms = 0
    max_rooms = 0
    s = e = 0
    while s < len(starts):
        if starts[s] < ends[e]:
            rooms += 1; s += 1
        else:
            rooms -= 1; e += 1
        max_rooms = max(max_rooms, rooms)
    return max_rooms

Alternative: min-heap approach. Sort by start time. Use a min-heap of end times. For each meeting: if heap[0] <= meeting.start, pop (reuse room). Always push meeting.end. Heap size = rooms needed. O(n log n).

Pattern 4: Employee Free Time (LC 759)

Given schedules of k employees (each as a list of non-overlapping intervals), find the common free time for all employees. Key insight: flatten all intervals into one list, sort by start time, merge overlapping intervals to get all “busy” time, then find the gaps between consecutive busy intervals.

def employee_free_time(schedules):
    all_intervals = []
    for schedule in schedules:
        all_intervals.extend(schedule)
    all_intervals.sort(key=lambda x: x.start)

    merged = [all_intervals[0]]
    for iv in all_intervals[1:]:
        if iv.start <= merged[-1].end:
            merged[-1].end = max(merged[-1].end, iv.end)
        else:
            merged.append(iv)

    free_times = []
    for i in range(1, len(merged)):
        free_times.append(Interval(merged[i-1].end, merged[i].start))
    return free_times

Other patterns: Non-Overlapping Intervals (LC 435): minimum removals to make non-overlapping. Greedy: sort by end time, greedily keep the interval that ends earliest. Remove the current interval if it overlaps with the last kept. Interval List Intersections (LC 986): find intersections of two sorted interval lists. Two pointers: advance the pointer of the interval that ends first. The intersection (if any) is [max(a.start, b.start), min(a.end, b.end)].

See also: Meta Interview Prep

See also: Coinbase Interview Prep

See also: LinkedIn Interview Prep

Scroll to Top