Merge Intervals

Medium Intervals Basics Original on LeetCode

Merge Intervals is a medium intervals problem solved with the basics pattern. The best approach, optimal (sort, then one sweep), runs in O(n log n) time and O(n) space. Below are 2 approaches in Java, from repeated pairwise merging up.

Problem

Given a collection of intervals, merge all overlapping intervals and return the non-overlapping intervals that cover exactly the same ranges.

Examples

Example 1

Input
intervals = [[1, 3], [8, 10], [2, 6], [15, 18]]
Output
[[1, 6], [8, 10], [15, 18]]

Example 2

Input
intervals = [[1, 4], [4, 5]]
Output
[[1, 5]]
Why
Touching intervals merge.

Constraints

  • 1 <= intervals.length <= 10^4; closed intervals.

Animated walkthrough

A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.

Concepts first, then the problem and every approach, step by step.

Space to play or pause · ← → to jump a step · click or drag the bar to seek

Solutions

Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.

ApproachTimeSpace
Repeated pairwise mergingO(n³)O(n)
Optimal (sort, then one sweep)O(n log n)O(n)

1Repeated pairwise merging

TimeO(n³)Up to n merge rounds, each scanning O(n²) pairs.
SpaceO(n)

Keep merging any two overlapping intervals until no pair overlaps.

  1. Loop: find any overlapping pair, replace it with its union, repeat.
Java
class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> list = new ArrayList<>(Arrays.asList(intervals));
        boolean changed = true;
        while (changed) {
            changed = false;
            outer:
            for (int i = 0; i < list.size(); i++)
                for (int j = i + 1; j < list.size(); j++) {
                    int[] a = list.get(i), b = list.get(j);
                    if (Math.max(a[0], b[0]) <= Math.min(a[1], b[1])) {
                        list.set(i, new int[] { Math.min(a[0], b[0]), Math.max(a[1], b[1]) });
                        list.remove(j);
                        changed = true;
                        break outer;
                    }
                }
        }
        list.sort((x, y) -> Integer.compare(x[0], y[0]));
        return list.toArray(new int[0][]);
    }
}

2Optimal (sort, then one sweep)

TimeO(n log n)
SpaceO(n)

After sorting by start, compare each interval with the last merged one. If it starts at or before that interval's end, extend the end with max; otherwise start a new merged interval.

  1. Sort by start.
  2. If out is empty or cur.start > last.end, append cur.
  3. Else last.end = max(last.end, cur.end).
Java
class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
        List<int[]> out = new ArrayList<>();
        for (int[] cur : intervals) {
            if (out.isEmpty() || cur[0] > out.get(out.size() - 1)[1]) out.add(new int[] { cur[0], cur[1] });
            else {
                int[] last = out.get(out.size() - 1);
                last[1] = Math.max(last[1], cur[1]);
            }
        }
        return out.toArray(new int[0][]);
    }
}

Edge cases to test

  • Unsorted input
  • One interval swallowing several others
  • Touching endpoints

Hints

Hint 1

Sort by start. Then each interval either extends the last merged interval or starts a new one.

FAQ

What is the best time complexity for Merge Intervals?

Optimal (sort, then one sweep) runs in O(n log n) time and O(n) extra space.

Which pattern does Merge Intervals use?

It is a intervals problem that uses the basics pattern. Other problems with the same pattern: Detect overlap unsorted, Detect overlap sorted intervals, Interval List Intersections.

Is there a brute force solution for Merge Intervals?

Yes. Repeated pairwise merging takes O(n³) time and O(n) space. Keep merging any two overlapping intervals until no pair overlaps.

Which edge cases should I test for Merge Intervals?

Unsorted input; One interval swallowing several others; Touching endpoints.