Skip to main content

56. Merge Intervals

mediumAsked at HubSpot

HubSpot 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^4
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 10^4

Examples

Example 1

Input
intervals = [[1,3],[2,6],[8,10],[15,18]]
Output
[[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

Input
intervals = [[1,4],[4,5]]
Output
[[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.

Output

Press Run or Cmd+Enter to execute

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 →