THN Interview Prep

56. Merge Intervals

At a Glance

  • Topic: greedy
  • Pattern: Merge Intervals (sort by start, linear merge)
  • Difficulty: Medium
  • Companies: Google, Facebook, Microsoft, Amazon, Bloomberg
  • Frequency: Very High
  • LeetCode: 56

Problem (one-liner)

Given a list of closed intervals [start, end], merge all overlapping / touching intervals and return the non-overlapping cover. Input: intervals. Output: merged list (any order is often accepted, but sorted by start is standard).

Recognition Cues

  • “Merge overlapping intervals”
  • Sort by start then sweep extending current merged segment while next.start <= currentEnd
  • Touching intervals [a,b] and [b,c] typically merge

Diagram

At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.

Loading diagram…

Approaches

  • Compare all pairsO(n²).
  • Sort + sweepO(n log n) time / O(n) output space. <- pick this in interview.

Optimal Solution

Go

package main

import "sort"

func merge(intervals [][]int) [][]int {
	if len(intervals) == 0 {
		return intervals
	}
	sort.Slice(intervals, func(left int, right int) bool {
		return intervals[left][0] < intervals[right][0]
	})
	merged := [][]int{intervals[0]}
	for index := 1; index < len(intervals); index++ {
		lastIndex := len(merged) - 1
		currentStart := intervals[index][0]
		currentEnd := intervals[index][1]
		if currentStart <= merged[lastIndex][1] {
			if currentEnd > merged[lastIndex][1] {
				merged[lastIndex][1] = currentEnd
			}
		} else {
			merged = append(merged, []int{currentStart, currentEnd})
		}
	}
	return merged
}

JavaScript

function merge(intervals) {
	if (intervals.length === 0) return intervals;
	const sorted = [...intervals].sort((left, right) => left[0] - right[0]);
	const merged = [sorted[0]];
	for (let index = 1; index < sorted.length; index++) {
		const lastIndex = merged.length - 1;
		const [currentStart, currentEnd] = sorted[index];
		if (currentStart <= merged[lastIndex][1]) {
			merged[lastIndex][1] = Math.max(merged[lastIndex][1], currentEnd);
		} else {
			merged.push([currentStart, currentEnd]);
		}
	}
	return merged;
}

Walkthrough

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

Sorted already. Merge [1,3] with [2,6][1,6]. Append [8,10], [15,18].

Invariant: after processing sorted prefix, merged covers exactly that prefix’s union with minimal disjoint intervals.

Edge Cases

  • Single interval
  • Fully nested intervals
  • Point intervals

Pitfalls

  • Forgetting sort first
  • Mutating shared interval slices during iteration if reused elsewhere

Similar Problems

Variants

  • Return merged length sum — derive from merged list.

Mind-Map Tags

#merge-intervals #sort #sweep-line #medium

Last updated on

Spotted something unclear or wrong on this page?

On this page