Home › DSA Patterns › Intervals
I

Intervals

Learn this one pattern and a whole family of "scheduling" and "range" problems stops feeling scary. Interviewers love intervals because the brute force is obvious and slow, and the clean answer takes one insight plus careful bookkeeping. That gap is the thing they are actually testing. The interval round is less about cleverness and more about three habits: sort first, say your overlap rule out loud, and settle the touching-endpoint edge before you write a line of code. Do those three and you pass.

DSA PatternsMedium11 min read
Who asks this, and how oftenInterview frequency: High

Most asked at Amazon. Here is how often this pattern shows up in each company's coding rounds.

Amazon
86
Meta
84
Google
82
Microsoft
76
Bloomberg
70
Relative frequency index from 0 to 100, based on commonly reported interview experiences. Use it as a guide to where this pattern pays off most, not an exact count.

If you remember five things

The whole pattern in one glance. Everything below defends these five calls.

  1. Overlap rule. Two intervals overlap when A.start <= B.end AND B.start <= A.end. Memorize this one line; it is the atom under every interval problem.
  2. Sort first. Sorting by start turns random pairs into a line you can sweep, dropping you from O(n^2) to O(n log n) and making half the overlap check free.
  3. Take the max end. When you merge, the new end is max(last.end, iv.end), never just iv.end. The nested-interval case silently breaks if you forget it.
  4. Know both sort keys. Merge and attend-meetings sort by start; maximum non-overlapping set sorts by end. Right logic plus wrong key equals wrong answer.
  5. Concurrency is not coverage. "How many rooms?" is a sweep or a heap, not a merge. Reaching for merge there answers a different question.

1The mental model (what this really is)#

An interval is just a pair: a start and an end. [2, 5] means "something is busy from 2 to 5."

  • Meetings on a calendar.
  • A booking on a hotel room.
  • A range of IP addresses.
  • The numbers can be times, positions, byte offsets, anything ordered along one axis.

Almost every interval problem reduces to one question: how do two intervals relate on a number line?

  • Two intervals either overlap or they do not. That is it.
  • Answer that cleanly and the rest is plumbing.

The single fact that unlocks most of these. Two intervals A and B overlap when:

A.start <= B.end AND B.start <= A.end
  • Say it out loud a few times: neither one starts after the other one ends.
  • If you remember nothing else, remember this.
  • The negation is just as useful: they are disjoint when A.end < B.start OR B.end < A.start, which is the "there is a gap" case.

The second big idea: sorting turns chaos into a line you can sweep.

  • Random order means you cannot reason about neighbors, so the naive approach compares every pair: O(n^2), about 100 million comparisons for 10,000 intervals.
  • Sort by start and each interval only needs comparing against the one next to it.
  • That one move drops you to O(n log n), roughly 10,000 * 14, about 140,000 operations for the same input.
  • Same answer, three orders of magnitude cheaper.
The one line that matters

A.start <= B.end AND B.start <= A.end is the whole pattern. Every template below is just this check plus bookkeeping about what to do on a yes versus a no. Burn the rule in and the problems stop looking different from each other.

2How to recognize it (the signals in a problem)#

Train your ear for these phrases. When you hear them, your hand should already be reaching for "sort by start."

  • "Merge overlapping..." anything.
  • "Can this person attend all meetings?" or "How many rooms do we need?"
  • "Insert a new interval and keep the list tidy."
  • "Find the minimum number of X to cover / remove / cover all gaps."
  • The input is literally a list of pairs [[1,3],[2,6],...].
  • Anything about free time, conflicts, double booking, ranges, or coverage.

One more tell, and it is a trap. If the problem counts how many things are active at the same time (max concurrent meetings, max planes in the air, peak traffic), that is a different animal.

  • You do not merge there. You sweep events.
  • Candidates reach for the merge template, get a clean merged list, then realize it answers the wrong question.
  • It is covered under variations below, because this is exactly where people trip.
Red flag that fails you here

Jumping to code before you have said your overlap rule and your sort key out loud. The interviewer cannot tell a lucky guess from a deliberate choice. Name "sort by start, overlap is iv.start <= last.end" first, then write. Silence here reads as "has not actually internalized the pattern."

3The template (how it works, with pseudocode)#

Ninety percent of interval problems start the exact same way. Burn this into muscle memory.

  • Step 1. Sort by start. (Sometimes by end, flagged later.)
  • Step 2. Walk the sorted list, keeping the "current" interval you are building or comparing against.
  • Step 3. For each next interval, ask: does it overlap the current one? Yes means do something (merge, count, reject). No means close out the current one and move on.

Here is the canonical merge template:

function merge(intervals):
    if intervals is empty: return []

    sort intervals by start ascending

    result = [ intervals[0] ]        # seed with the first one

    for each iv in intervals[1:]:
        last = result[-1]            # the interval we're currently extending

        if iv.start <= last.end:             # they overlap (or touch)
            last.end = max(last.end, iv.end) # swallow it
        else:
            result.append(iv)                # gap: start a fresh interval

    return result

Why the overlap check shrank to iv.start <= last.end.

  • Sorting already guarantees last.start <= iv.start, so the other half of the two-sided condition is free.
  • That is the payoff of sorting: you never compare backward.

Why max(last.end, iv.end) and not just iv.end.

  • Take [1, 10] then [2, 3]. The second is fully inside the first.
  • Blindly take iv.end and you shrink to [1, 3], losing coverage from 3 to 10.
  • Always take the max. This exact slip fails otherwise-correct solutions on the hidden "nested interval" test case.
Pause before you read on: your input is [[1,4],[2,3]] and you write last.end = iv.end instead of the max. What final answer do you print, and why is it wrong?
Reveal the answer
You print [[1,3]]. The second interval [2,3] overlaps [1,4], so you enter the merge branch, but setting last.end = iv.end drops the end from 4 to 3 and throws away coverage from 3 to 4. The correct output is [[1,4]], since [2,3] is fully contained. This is the nested-interval bug, and it is the single most common way a correct-looking solution fails a hidden test.

Here is the shape of the walk, so you can see why it stays one pass:

flowchart TD A[Sort by start] --> B[Seed result with first interval] B --> C{More intervals left} C -->|No| G[Return result] C -->|Yes| D{iv start LE last end} D -->|Overlap| E[last end becomes max of last end and iv end] D -->|Gap| F[Append iv as new current] E --> C F --> C
The one-pass merge loop. Notice there is exactly one overlap check and one else branch, and no arrow ever points backward: you only ever compare the new interval against the last thing in result, which is why it is linear after the sort.

4A worked example (walk through one problem step by step)#

The classic: Merge Intervals. Given [[1,3], [2,6], [8,10], [15,18]], return the list with all overlaps merged.

  • Sort by start. Already sorted here: [1,3], [2,6], [8,10], [15,18]. Do not skip this in your head just because it looks sorted. Say "first I sort by start, O(n log n)." It signals you know the pattern and protects you when the grader hands you an unsorted input on the next run.
  • Seed the result with the first interval. result = [[1,3]]. The interval you are holding open is [1,3].
  • Next: [2,6]. Is 2 <= 3? Yes, they overlap. Merge: new end is max(3, 6) = 6. Held interval becomes [1,6]. result = [[1,6]]. Narrate this one: the 2 falls inside [1,3], the ranges touch, and together they cover 1 all the way to 6. One continuous block.
  • Next: [8,10]. Is 8 <= 6? No. 8 is past where the current block ends, so there is a gap between 6 and 8. Close out [1,6] for good and start holding [8,10]. result = [[1,6], [8,10]].
  • Next: [15,18]. Is 15 <= 10? No. Another gap. Close [8,10], start holding [15,18]. result = [[1,6], [8,10], [15,18]].

Done. Final answer: [[1,6], [8,10], [15,18]].

  • Walk it once on paper and you feel the "current held interval" idea do all the work.
  • You never look backward: you only compare the new interval against the last thing in your result.
  • That is why it is linear after the sort: n comparisons, n appends at most, no nested loop anywhere.

5Variations and gotchas#

The merge template is the base. Here are the mutations interviewers throw at you.

Insert Interval (list already sorted).

  • Given a sorted, non-overlapping list and one new interval.
  • Three phases: add all intervals that end before the new one starts, merge everything that overlaps the new one into it, then add all intervals that start after the new one ends.
  • O(n), no sorting needed since the input is pre-sorted.
  • The trap is phase two: keep absorbing while interval.start <= new.end, taking the min of starts and the max of ends, before you push the one merged block.

Can attend all meetings?

  • Sort by start.
  • If any meeting starts before the previous one ended (curr.start < prev.end), return false.
  • One pass, O(n log n) for the sort, O(1) extra space.

Meeting Rooms II (minimum rooms). This is the "max concurrent" family, and it does not use the merge template. Two clean approaches:

  1. Two sorted arrays. Pull out all start times and all end times, sort each. Walk a pointer through starts. Every time a meeting starts before the earliest unmatched end, you need a new room. Otherwise free a room by advancing the end pointer.
  2. Min-heap of end times. Sort by start. For each meeting, if the heap's smallest end time is <= current start, pop it (reuse that room). Push the current end. The heap size at its peak is your answer.

  3. Both are O(n log n).

  4. The heap version generalizes nicely: swap the heap for a counter and you have the line sweep below, swap it for a sum and you have Car Pooling.

Event sweep / line sweep (max people in the room at once).

  • Turn each interval into two events: (start, +1) and (end, -1).
  • Sort all events, sweep left to right, keep a running counter, track the max.
  • Watch the tie-break: if a meeting ends at the same time another starts, do they share a room? Usually an end at the same instant frees the room first, so process -1 before +1 at equal timestamps.
  • Ask the interviewer about this edge. It shows maturity, and it is the difference between an answer of 2 and an answer of 1 on the boundary case.

Sort by END instead of start. The one people miss.

  • For "maximum number of non-overlapping intervals you can keep" (interval scheduling / "erase overlap"), sort by end time and greedily keep whatever finishes earliest.
  • Finishing early leaves the most room for others.
  • Sorting by start here gives wrong answers on inputs like [[1,100],[2,3],[3,4]], where keeping the long early-starting interval blocks two short ones.
  • Know both keys and know why.

Closed vs open, touching endpoints.

  • Is [1,2] and [2,3] an overlap or not? Depends on the problem.
  • For merging, touching usually counts (<=), so they fuse into [1,3].
  • For "attend all meetings," a meeting ending exactly when the next starts is usually fine (<).
  • Clarify this out loud. It is a real source of off-by-one bugs and a free place to show you think about boundaries.
From the interviewer's chair

When a candidate stops and asks "does touching count as overlap here?" before coding, I relax. It tells me they have been bitten by this before and they test boundaries on purpose. The candidates who silently pick < or <= and hope are the ones I have to probe, and that probe eats the clock they needed for the hard part.

6Complexity#

For the whole merge / attend-meetings / insert family:

  • Time: O(n log n), dominated by the sort. The sweep after it is O(n).
  • Space: O(n) for the output list, or O(log n) to O(n) for the sort's internal memory depending on the language (Python's Timsort is O(n), a typical in-place quicksort is O(log n)). If asked to merge in place, you can sometimes get O(1) extra, but the output usually forces O(n).

For the heap-based room-counting:

  • O(n log n) time.
  • O(n) space for the heap in the worst case (every meeting overlaps, so the heap holds all n ends at once).

The one exception: Insert Interval into an already-sorted list is O(n), because you skip the sort.

  • Catch that the input is pre-sorted and still sort it, and you have left the better answer on the table, dropping from O(n) to O(n log n) for no reason.
  • Interviewers notice. This is the single most common way a candidate turns a strong answer into an average one on this problem.

7Mistakes that cost people the round#

These sink candidates who clearly knew the idea.

  • Forgetting max(last.end, iv.end). The fully-nested case ([1,10] then [2,3]) silently breaks and you lose coverage. The number one bug.
  • Using < when you need <= for touching intervals, or the reverse. Settle it with the interviewer before you code. Guessing costs a test case and the look of carelessness.
  • Sorting by the wrong key. Merge and attend-meetings: sort by start. Maximum non-overlapping set: sort by end. Mix these up and your logic is right but your answer is wrong, the worst way to fail because the code reads as correct.
  • Trying to merge for a "max concurrent rooms" problem. Merging tells you coverage, not concurrency. Different question, different tool (heap or sweep).
  • Mutating the input list while iterating it. Build a fresh result. Do not delete from the array you are looping over, and watch that merging in place does not alias the caller's objects.
  • Not handling empty input. One line at the top. Free points, and it shows you test your own code.
  • Over-nesting conditionals. The clean solution has one overlap check and an else. Four nested ifs means you have lost the thread. Step back and re-derive from the single overlap rule.

Right logic with the wrong sort key is the worst failure: the code reads as correct and the answer is still wrong.

8Your practice path (named problems by difficulty)#

Do them in this order. Each one adds exactly one new idea.

Warm up (Easy):

  • Merge Sorted Array (gets you comfortable with two sorted sequences)
  • Meeting Rooms (the yes/no "can attend all" version)
  • Summary Ranges

Core (Medium), do every one of these:

  • Merge Intervals (the template, nail it blindfolded)
  • Insert Interval (the three-phase trick, spot the pre-sorted input)
  • Non-overlapping Intervals (sort by end, greedy)
  • Meeting Rooms II (min heap / sweep, max concurrency)
  • Interval List Intersections (two-pointer over two sorted lists)
  • Minimum Number of Arrows to Burst Balloons (greedy, sort by end)
  • Car Pooling (event sweep with a running sum)
  • My Calendar I (overlap check on inserts)

Stretch (Hard):

  • Employee Free Time (merge across many lists, then find gaps)
  • My Calendar II / III (overlap counting with a sweep)
  • Data Stream as Disjoint Intervals (maintain merged intervals live)

The four that mean you are ready.

  • If you can do Merge Intervals, Insert Interval, Non-overlapping Intervals, and Meeting Rooms II without looking anything up, you are ready for almost any interval question.
  • Those four cover the three keys (sort by start, sort by end, and the heap/sweep concurrency tool), and everything else is a remix of them.
Follow-ups the interviewer will ask (and your answers)
"The input is already sorted and non-overlapping. Can you do better than O(n log n)?"
Yes, if the task is Insert Interval. Skip the sort and do the three-phase scan: copy intervals that end before the new one starts, merge everything that overlaps (min of starts, max of ends) into a single block, then copy the rest. That is O(n). Sorting a pre-sorted input throws the win away.
"Do [1,2] and [2,3] overlap?"
Depends on whether endpoints are closed. I would ask. For a merge problem, touching usually counts, so I use iv.start <= last.end and fuse them into [1,3]. For "can attend all meetings," touching is usually fine, so I use curr.start < prev.end. I state which one I picked before coding so the boundary is not a guess.
"Why does merging fail for counting the maximum concurrent meetings?"
Merging collapses overlapping intervals into coverage, which loses the count of how many were stacked at once. Concurrency needs a different tool: turn each interval into a +1 at start and a -1 at end, sort the events, sweep with a running counter, and track the peak. Or use a min-heap of end times and read its peak size.
"For maximum non-overlapping intervals, why sort by end and not start?"
Greedily keeping whichever interval finishes earliest leaves the most room for the ones after it, which is the classic activity-selection argument. Sort by start and a long early interval like [1,100] blocks two short ones like [2,3] and [3,4] that would both fit. Sort by end and you keep the two short ones.
"At equal timestamps in a line sweep, do you process the start or the end first?"
Usually the end first, so a room freed at time t is reused by a meeting starting at t and they do not count as concurrent. That is the difference between an answer of 1 and 2 on the boundary. I confirm the intended semantics with the interviewer, since some variants want the opposite.

What you can now explain in the room

  • The exact overlap rule (A.start <= B.end AND B.start <= A.end) and why sorting makes half of it free.
  • The merge template in one pass, and why the new end must be max(last.end, iv.end).
  • When to sort by start versus by end, with a concrete input that punishes the wrong key.
  • Why "how many rooms" is a sweep or a heap, not a merge, and how the two approaches relate.
  • The touching-endpoint boundary question and why you settle it out loud before coding.
  • Why Insert Interval into a pre-sorted list is O(n), and how sorting it anyway drops you to O(n log n).

Want to see which companies lean on intervals and how they phrase them? Check the company guides to match this pattern to the rooms you'll actually sit in.

Get a prep plan built around your Intervals interview

Tell us the role and your interview date. We will send back a dated, day by day plan. Free.

Thanks. Check your inbox, your Intervals prep plan is on the way.