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.
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.
| Metric | Value |
|---|---|
| Total Interview Appearances | 127 verified mentions |
| Companies That Ask It | 47 companies |
| Global Rank | #3 out of 10,385 questions |
| Difficulty | Medium |
| Core Patterns | Array, Sorting, Greedy |
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.
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.
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].
next.start <= current.end ā merge by extending end to max(current.end, next.end)next.start == current.end ā also counts as overlap per constraintsnext.start > current.end ā push current to result, start fresh with nextThe 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.
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.
current.start <= last.end) ā merge by updating last.end = max(last.end, current.end)Input: [[1,3],[2,6],[8,10],[15,18]] ā already sorted by start.
| Step | Current Interval | Last in Result | Overlap? | 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]] |
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
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()][]);
}
}
/**
* @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;
};
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."
Merge Intervals is the gateway to an entire family of interval problems. Interviewers at Google, Amazon, and Bloomberg regularly follow up with these variants.
"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.
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
"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).
"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).
"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.
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)
"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.
| Problem | Key Operation | Sort By | Data Structure |
|---|---|---|---|
| LC #56 Merge | Merge overlapping | Start time | Result list |
| LC #57 Insert | Insert + merge | Already sorted | Result list |
| LC #435 Non-Overlap | Min removals | End time | Greedy counter |
| LC #252 Rooms I | Can attend all? | Start time | Simple scan |
| LC #253 Rooms II | Min rooms needed | Start time | Min-heap |
| LC #759 Free Time | Find gaps | Start time | Result list |
The sort-and-scan interval pattern signals itself with specific keywords. Train yourself to recognize them immediately.
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.
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.
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.
One problem at a time. One review at a time. Future you will thank present you.