Merge Intervals: Optimal Solution (Data-Backed Guide)

By DSA Prep Team · March 4, 2026 · 9 min read · Algorithms

Merge Intervals is the #3 most asked LeetCode problem globally — and the one most candidates underprepare for.

Our analysis of 10,385 verified interview questions across 259 companies shows Merge Intervals appeared 127 times across 47 companies — including Google, Amazon, Meta, Bloomberg, Microsoft, Goldman Sachs, Citadel, and Databricks.

Unlike Two Sum or Stock problems, Merge Intervals tests a distinct thinking pattern: sort first, then use a greedy scan with a running "current interval." This same pattern appears across 5 other interval problems that regularly come up as follow-ups. Master the pattern here and you unlock the entire family.

Table of Contents

The Data: Why This Gets Asked at Top Companies

Merge Intervals is a favourite at companies that work with scheduling, calendars, time-series data, and resource allocation — which is nearly every major tech company.

MetricValue
Total Interview Appearances127 verified mentions
Companies That Ask It47 companies
Global Rank#3 out of 10,385 questions
DifficultyMedium
Core PatternsArray, Sorting, Greedy

šŸ“Œ Companies That Ask This Problem

Google, Amazon, Meta, Microsoft, Bloomberg, Goldman Sachs, Citadel, Databricks, Apple, Adobe, Atlassian, LinkedIn, Dropbox, Airbnb, Capital One, J.P. Morgan, Morgan Stanley, ByteDance, Flipkart, Expedia, Cisco, Disney, and 25 more.

Notice the spread: FAANG, finance (Goldman, Citadel, J.P. Morgan, Morgan Stanley), and product companies (Dropbox, LinkedIn, Expedia) all ask this. The underlying reason: interval merging shows up naturally in calendar apps, meeting schedulers, log processors, and resource managers — real engineering problems these companies deal with daily.

Problem Statement

LeetCode #56 — Merge Intervals

Given an array of intervals where intervals[i] = [start_i, end_i], merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input.

Examples
Input:  intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: [1,3] and [2,6] overlap → merge to [1,6].

Input:  intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: [1,4] and [4,5] touch at 4 → merge to [1,5].

Input:  intervals = [[1,4],[0,4]]
Output: [[0,4]]
Explanation: After sorting: [0,4] and [1,4] → merge to [0,4].

āš ļø Two Overlap Cases to Handle

The Core Intuition: Why Sort First?

The key question is: why does sorting make this problem easy?

Without sorting, any interval could potentially overlap with any other. You'd have to compare every pair — O(n²). But once you sort by start time, a crucial property emerges: if interval A and interval C don't overlap (A ends before C starts), then no interval between them in sorted order can overlap with A either.

This means you only ever need to compare the current interval with the last interval in your result list. You never need to look further back. That's what makes a single greedy pass possible after sorting.

šŸ’” The Key Property After Sorting

After sorting by start time, two intervals [a, b] and [c, d] (where a ≤ c) overlap if and only if c ≤ b. You never need to compare non-adjacent intervals in the sorted order.

The Algorithm: Sort + Greedy Merge

  1. Sort all intervals by their start time.
  2. Initialize result list with the first interval.
  3. Iterate through remaining intervals. For each interval:
    • If it overlaps with the last interval in result (current.start <= last.end) → merge by updating last.end = max(last.end, current.end)
    • If it doesn't overlap → append it to result as a new interval
  4. Return the result list.

Visual Walkthrough

Input: [[1,3],[2,6],[8,10],[15,18]] — already sorted by start.

StepCurrent IntervalLast in ResultOverlap?Result
Init———[[1,3]]
1[2,6][1,3]āœ… 2 ≤ 3 → merge[[1,6]]
2[8,10][1,6]āŒ 8 > 6 → new[[1,6],[8,10]]
3[15,18][8,10]āŒ 15 > 10 → new[[1,6],[8,10],[15,18]]

Code in Python, Java & JavaScript

Python 3
def merge(intervals: list[list[int]]) -> list[list[int]]:
    # Sort by start time
    intervals.sort(key=lambda x: x[0])

    merged = [intervals[0]]

    for current in intervals[1:]:
        last = merged[-1]

        if current[0] <= last[1]:
            # Overlap — extend the end if needed
            last[1] = max(last[1], current[1])
        else:
            # No overlap — start a new interval
            merged.append(current)

    return merged
Java
class Solution {
    public int[][] merge(int[][] intervals) {
        // Sort by start time
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);

        List<int[]> merged = new ArrayList<>();
        merged.add(intervals[0]);

        for (int i = 1; i < intervals.length; i++) {
            int[] last = merged.get(merged.size() - 1);
            int[] current = intervals[i];

            if (current[0] <= last[1]) {
                // Overlap — extend the end
                last[1] = Math.max(last[1], current[1]);
            } else {
                // No overlap — add new interval
                merged.add(current);
            }
        }

        return merged.toArray(new int[merged.size()][]);
    }
}
JavaScript
/**
 * @param {number[][]} intervals
 * @return {number[][]}
 */
var merge = function(intervals) {
    // Sort by start time
    intervals.sort((a, b) => a[0] - b[0]);

    const merged = [intervals[0]];

    for (let i = 1; i < intervals.length; i++) {
        const last = merged[merged.length - 1];
        const current = intervals[i];

        if (current[0] <= last[1]) {
            // Overlap — extend the end
            last[1] = Math.max(last[1], current[1]);
        } else {
            // No overlap — add new interval
            merged.push(current);
        }
    }

    return merged;
};

Complexity Analysis

šŸ“Š Complexity Summary

Interview-ready explanation: "We sort in O(n log n) then do a single O(n) greedy pass. Overall time is O(n log n). Space is O(n) for the output — or O(log n) if we don't count output space and the sort is in-place."

Interval Problem Family: 5 Must-Know Variants

Merge Intervals is the gateway to an entire family of interval problems. Interviewers at Google, Amazon, and Bloomberg regularly follow up with these variants.

Variant 1: Insert Interval (LeetCode #57)

"Given a sorted list of non-overlapping intervals and a new interval, insert it and merge if necessary."

Insight: Walk through in three phases — add all intervals ending before the new one starts, merge all overlapping intervals with the new one, then add the rest. O(n) time — no sort needed since input is already sorted.

Python — LC #57 Insert Interval
def insert(intervals, newInterval):
    result = []
    i, n = 0, len(intervals)

    # Phase 1: add all intervals ending before newInterval starts
    while i < n and intervals[i][1] < newInterval[0]:
        result.append(intervals[i])
        i += 1

    # Phase 2: merge all overlapping intervals
    while i < n and intervals[i][0] <= newInterval[1]:
        newInterval[0] = min(newInterval[0], intervals[i][0])
        newInterval[1] = max(newInterval[1], intervals[i][1])
        i += 1
    result.append(newInterval)

    # Phase 3: add remaining intervals
    while i < n:
        result.append(intervals[i])
        i += 1

    return result

Variant 2: Non-Overlapping Intervals (LeetCode #435)

"Find the minimum number of intervals to remove to make the rest non-overlapping."

Insight: Sort by end time (not start). Greedily keep the interval that ends earliest — this leaves the most room for future intervals. Count how many you must skip. O(n log n).

Variant 3: Meeting Rooms I (LeetCode #252)

"Given meeting time intervals, can a person attend all meetings?"

Insight: Sort by start time. If any meeting starts before the previous one ends, return false. O(n log n).

Variant 4: Meeting Rooms II (LeetCode #253)

"Find the minimum number of conference rooms required."

Insight: Use a min-heap of end times. For each new meeting, if the earliest-ending meeting is done, reuse that room. Otherwise open a new room. Heap size = minimum rooms needed.

Python — LC #253 Meeting Rooms II
import heapq

def minMeetingRooms(intervals):
    if not intervals:
        return 0

    intervals.sort(key=lambda x: x[0])
    heap = []  # min-heap of end times

    for start, end in intervals:
        if heap and heap[0] <= start:
            heapq.heapreplace(heap, end)  # reuse room
        else:
            heapq.heappush(heap, end)     # open new room

    return len(heap)

Variant 5: Employee Free Time (LeetCode #759)

"Given schedules of all employees, find the free time intervals common to all."

Insight: Flatten all intervals, sort, merge overlapping ones (same as #56), then collect the gaps between consecutive merged intervals.

šŸ“‹ Interval Problem Family — Quick Reference

ProblemKey OperationSort ByData Structure
LC #56 MergeMerge overlappingStart timeResult list
LC #57 InsertInsert + mergeAlready sortedResult list
LC #435 Non-OverlapMin removalsEnd timeGreedy counter
LC #252 Rooms ICan attend all?Start timeSimple scan
LC #253 Rooms IIMin rooms neededStart timeMin-heap
LC #759 Free TimeFind gapsStart timeResult list

The Bigger Pattern: When Intervals Appear

The sort-and-scan interval pattern signals itself with specific keywords. Train yourself to recognize them immediately.

šŸ’” The Universal Interval Template

For almost every interval problem: sort by start time → initialize result with first interval → scan and compare each interval against the last result interval → merge or append. Meeting Rooms II adds a heap on top of this base. Everything else is a variation of this template.

How to Actually Remember This

With 127 appearances at 47 companies — including every major FAANG and finance firm — you will see an interval problem in a serious interview. The sort-then-merge pattern is mechanical once internalized, but it requires practice to execute cleanly under pressure.

āœ… Your Spaced Repetition Schedule

  1. Today (Day 0): Solve LC #56 from scratch. Then immediately solve LC #252 (Meeting Rooms I).
  2. Day 3: Solve LC #57 (Insert Interval) and LC #435 (Non-Overlapping). Explain why you sort by end for #435.
  3. Day 7: Solve LC #253 (Meeting Rooms II) with a heap. Trace through a 4-meeting example on paper.
  4. Day 14: Pick two random interval problems. Identify the pattern before writing any code.
  5. Day 30: Solve all 5 variants back to back in one session. Aim for under 15 minutes each.

Tag all 6 interval problems together on DSAPrep.dev under Intervals and Sorting. The spaced repetition system groups related problems and surfaces them together — so reviewing one reinforces the whole family.

Track All Interval Variants on DSAPrep.dev →

One problem at a time. One review at a time. Future you will thank present you.