56. Merge Intervals
mediumAsked at HubSpotHubSpot asks Merge Intervals because overlapping-range problems appear constantly in their scheduling, deal-stage overlap detection, and meeting de-duplication workflows — and they want to see clean sort-then-scan logic with tight boundary handling.
By Alex Chen, Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in HubSpot loops.
- Glassdoor (2026-Q1)— HubSpot SWE onsite reports frequently mention Merge Intervals as a core medium problem testing sorting and greedy scanning.
- Blind (2025-10)— HubSpot candidates cite Merge Intervals in coding-round write-ups, noting focus on edge cases like touching intervals.
Problem
Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.
Constraints
1 <= intervals.length <= 10^4intervals[i].length == 20 <= starti <= endi <= 10^4
Examples
Example 1
intervals = [[1,3],[2,6],[8,10],[15,18]][[1,6],[8,10],[15,18]]Explanation: Intervals [1,3] and [2,6] overlap at [2,3], so they merge to [1,6].
Example 2
intervals = [[1,4],[4,5]][[1,5]]Explanation: Intervals [1,4] and [4,5] are considered overlapping (touching at 4).
Approaches
1. Sort then linear scan
Sort intervals by start time. Walk through them linearly: if the current interval's start is within the last merged interval, extend the end if needed. Otherwise, start a new merged interval.
- Time
- O(n log n)
- Space
- O(n) output
function merge(intervals) {
if (intervals.length === 0) return [];
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 [start, end] = intervals[i];
if (start <= last[1]) {
// Overlapping or touching — extend the end
last[1] = Math.max(last[1], end);
} else {
merged.push([start, end]);
}
}
return merged;
}Tradeoff: O(n log n) dominated by sorting; the scan is O(n). Sorting by start time is the only preprocessing needed — after that, each interval is processed exactly once. Use Math.max for the end because a fully contained interval (e.g., [1,10] followed by [2,5]) must not shrink the end.
HubSpot-specific tips
State the sorting rationale upfront: 'After sorting by start time, overlapping intervals are always adjacent, so a single left-to-right scan suffices.' HubSpot interviewers probe the touching-interval case ([1,4],[4,5] → [1,5]) — confirm that your condition is start <= last[1] not start < last[1]. They also check the fully-contained case ([1,10],[2,5]) — confirm you use Math.max on the end, not just take the current end.
Common mistakes
- Using strict less-than (start < last[1]) instead of (start <= last[1]) — misses touching intervals.
- Not using Math.max for the end — a fully-contained interval would incorrectly shrink the merged end.
- Sorting by end time instead of start time — breaks the adjacency guarantee.
- Modifying the input array in place without noting it — either copy first or inform the interviewer.
Follow-up questions
An interviewer at HubSpot may pivot to one of these next:
- Insert Interval (LC 57) — insert a new interval into a sorted list of non-overlapping intervals.
- Non-overlapping Intervals (LC 435) — find the minimum number of intervals to remove to make the rest non-overlapping.
- Meeting Rooms II (LC 253) — find the minimum number of meeting rooms required.
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why sort by start time and not end time?
Sorting by start time ensures all potentially overlapping intervals are adjacent. An interval with a later start cannot overlap with an interval that ends before it, so scanning left-to-right is sufficient.
What does 'touching' mean and why does it merge?
Intervals [1,4] and [4,5] share endpoint 4 — there's no gap between them. The problem treats this as overlapping, so they merge to [1,5]. The condition start <= last[1] captures this.
What if all intervals are the same?
Sorting is a no-op; the first interval is pushed to merged; all subsequent intervals satisfy start <= last[1] and only extend end — correctly producing one merged interval.
Practice these live with InterviewChamp.AI
Drill Merge Intervals and other HubSpot interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.
Practice these live with InterviewChamp.AI →