Intervals
Sort them the right way, and one sweep answers merge, schedule and room-count questions.
01 · why it exists
Why this exists, and the weight it carries
since?
Interval merging (sort by start)
A folklore technique with no single inventor: it's what any "union of ranges" code does after sorting. The HTML standard even requires browsers to keep a video's buffered ranges merged this way.
its jobs today
- Browsers: a media element's
bufferedandseekableranges must be normalized: sorted, not overlapping and not touching (HTML standard). - Calendars and booking systems: merge busy blocks to show free slots (Employee Free Time).
- Genomics:
bedtools mergecollapses overlapping genome intervals before coverage is counted.
the weight it carries
Illustrative: 10⁴ busy blocks from a team calendar. Merging any overlapping pair again and again: up to n merges × n² pair checks ≈ 10¹² steps. Sort + one sweep: about 10⁴ × log₂ 10⁴ ≈ 1.3 × 10⁵ comparisons + 10⁴ steps.
without it
Overlapping ranges get double-counted (coverage looks bigger than it is), and every free-slot search compares every pair.
when · why · how
- when
- You need the union of ranges, or you insert into / search a set of disjoint ranges.
- why
- After sorting by start, only the last group can overlap the next interval: O(n log n) in total instead of O(n²) pair checks.
- how
Arrays.sort(iv, (a, b) -> Integer.compare(a[0], b[0])), aList<int[]> merged, andlast[1] = Math.max(last[1], cur[1]).
since?
Interval scheduling (earliest finish first)
No documented first inventor. Textbooks treat it as the model greedy algorithm: Cormen, Leiserson and Rivest's Introduction to Algorithms (1990) says its correctness proof follows Gavril's 1972 paper on chordal graphs, and Kleinberg & Tardos (2005) open their greedy chapter with it.
its jobs today
- One shared resource (a meeting room, a GPU, a test device) and many requests: accept the most requests that don't clash.
- Fewest removals to make a schedule clash-free (LC 435), and the fewest points that hit every interval (LC 452).
the weight it carries
Illustrative: 25 requests for one room. Trying every subset: 2²⁵ ≈ 3.4 × 10⁷ subsets, each checked. Earliest finish first: sort 25 items (about 25 × log₂ 25 ≈ 116 comparisons) + 25 checks.
without it
Scheduling the most jobs would fall back to a DP (the O(n²) LIS-style one), or brute force over subsets.
when · why · how
- when
- Keep the most intervals, remove the fewest, or cover all of them with the fewest points.
- why
- The earliest-ending interval leaves the most room, and an exchange argument proves it. O(n log n) for the sort, O(n) for the pass.
- how
- Sort by end with
Integer.compare(a[1], b[1]), keeplastEnd, take an interval whenstart >= lastEnd(orstart > arrowXfor closed balloons).
since1971–1979
Interval partitioning (rooms = maximum overlap)
Akihiro Hashimoto & James Stevens; U. I. Gupta, D. T. Lee & J. Y.-T. Leung
Chip designers had to route many wires, each a horizontal interval, through a channel using as few tracks as possible: the same as fitting meetings into rooms. Hashimoto and Stevens's 1971 left-edge algorithm sorts the wires by their left end and puts each one on the first track that is free. In 1979 Gupta, Lee and Leung gave an O(n log n) method for this channel-assignment problem and showed it is the best possible. The number of tracks it reaches is the depth: the most intervals covering one point. Kolen et al.'s 2007 survey traces this history.
the problem it solvedFitting every interval onto the fewest parallel resources (tracks, rooms, machines) with no clashes.
its jobs today
- Room and hall booking: the rooms you need = the peak number of overlapping bookings.
- Chip layout: the left-edge algorithm assigns wires to channel tracks.
- Capacity planning: the machines needed for a set of time-boxed jobs is their maximum overlap.
the weight it carries
Illustrative: 10⁴ meetings. Counting, for every meeting's start, how many others are running: 10⁴ × 10⁴ = 10⁸ checks. Heap: sort (~1.3 × 10⁵ comparisons) + up to 2 × 10⁴ heap operations (one offer and at most one poll per meeting) of about log₂ 10⁴ ≈ 13 steps each.
without it
Room counts would need an O(n²) scan, or a guess that either over-books or wastes rooms.
when · why · how
- when
- "Minimum rooms / platforms / machines", "max concurrent", "capacity at any moment".
- why
- The answer is the maximum overlap; a min-heap of end times (or sorted starts vs sorted ends) finds it in O(n log n).
- how
PriorityQueue<Integer>of end times:poll()whenpeek() <= start, thenoffer(end); the heap's final size is the answer.
since1976
Sweep line & difference array
Michael Ian Shamos & Dan Hoey
In 1976 Shamos and Hoey asked: among n line segments, do any two cross? Checking every pair is O(n²). Their algorithm swept an imaginary line across the plane, stopping only at events (segment ends) in sorted order: O(n log n). Bentley and Ottmann (1979) extended the sweep to report every crossing. On a number line, the same idea is simply: sort the start and end events, walk them in order, keep a running count.
the problem it solvedAnswering "what overlaps what" without testing every pair.
its jobs today
- Geometry and maps: finding crossing roads or boundaries and overlapping shapes.
- Capacity checks along a route or a timeline: people on board, concurrent users, bandwidth booked per minute (difference arrays).
- Offline queries: sort the queries together with the events and answer them all in one pass (LC 1851).
the weight it carries
Illustrative: 1,000 trips on a 1,000-km road. Checking every km against every trip: 1,001 × 1,000 ≈ 10⁶ steps. Difference array: 2 writes per trip + one pass over 1,001 points, about 3,000 steps.
without it
Every "how many at once?" question becomes a pair-by-pair or point-by-point scan.
when · why · how
- when
- Max overlap, capacity along a line, many range updates then one read, or many point queries over intervals.
- why
- Only event points matter: O(n log n) with sorted events, or O(n + R) with a difference array over a small range R.
- how
- Small coordinates:
int[] diff,diff[s] += k; diff[e] -= k, then a running sum. Big or sparse:TreeMap<Integer, Integer>withmerge(x, k, Integer::sum), then iteratevalues().
02 · plain english
The idea in 30 seconds
An interval is a stretch [start, end]: a meeting, a booking, a downloaded piece of a video, a balloon on the x-axis.
Almost every interval problem starts with a sort: by start to merge or sweep, by end to keep the most or to stab them with the fewest points.
After the sort, one left-to-right pass, with a variable or a min-heap of end times, gives the answer in O(n log n).
picture this
The grey buffered bar under a video. As you skip around, the browser downloads pieces as [start, end] time ranges and keeps them merged: the HTML standard says the buffered ranges must be sorted, never overlap and never touch, so touching pieces are folded into one. That is Merge Intervals, running inside every browser's video player.
03 · remember
What you must know
- Overlap test for closed [a, b] and [c, d]:
a <= d && c <= b. For half-open meetings [a, b):a < d && c < b. One<vs<=decides whether touching counts. - Read the touching rule every time. LC 56 merges [1,4] and [4,5]. LC 435 and meeting rooms let [1,2] and [2,3] live together. In LC 452 one arrow at x = 2 bursts both [1,2] and [2,3].
- Sort by start to combine or sweep (merge, insert, meeting rooms, free time). After the sort, the next interval can only overlap the last group.
- Sort by end to keep the most intervals or to stab them with the fewest points (LC 435, LC 452). The earliest finisher leaves the most room: the exchange argument from the Greedy chapter.
- Rooms needed = the most intervals overlapping at one moment. Get it with a min-heap of end times, or with two sorted arrays (starts and ends).
- Sweep line / difference array: +k at a start, −k at an end, then a running sum. An
int[]for small coordinates, aTreeMapfor huge or sparse ones. - Offline queries: when many points ask about many intervals (LC 1851), sort the queries too and sweep both together with a heap.
- Comparator safety:
Integer.compare(a[0], b[0]), nevera[0] - b[0]. LC 452's coordinates span the wholeintrange.
04 · see it
Play with it in 3D
Press Space to play, ←/→ to step, drag to move, ? for all shortcuts. Try your own input.
Merge intervals
After sorting by start, each interval either stretches the current group or opens a new one.
Insert interval: copy, absorb, copy
The list is already sorted, so no sort: copy what ends before, absorb what overlaps, copy what starts after.
Activity selection on a timeline
Sorted by end time. Each activity is kept or skipped by one comparison with `lastEnd`.
Meeting rooms with a min-heap of end times
The heap's top is the room that frees up first. If it's free by the next start, reuse it.
Sweep line: how many rooms?
Starts and ends sorted on their own. A start before the earliest unused end means a new room.
05 · cost
Time & space, explained
| Time | Extra space | why | |
|---|---|---|---|
| Try every subset | O(2ⁿ · n) | O(n) | 2ⁿ subsets, each checked in O(n) after sorting. Hopeless past n ≈ 25. |
| DP over intervals sorted by start | O(n²) | O(n) | For each interval, look back at every earlier one (an LIS-style DP). |
| Greedy: sort by end + one pass | O(n log n) | O(1)–O(n) | The sort dominates. The pass is O(n). Space is whatever the sort needs. |
| Time | Extra space | why | |
|---|---|---|---|
Sort intervals (Arrays.sort(int[][], cmp)) | O(n log n) | O(n) | Rows are objects, so Java uses its stable merge sort (TimSort), which may need up to n/2 temporary slots. |
| Merge overlapping intervals | O(n log n) | O(n) | Sort by start, then one pass. The output can hold n intervals. |
| Insert into a sorted, disjoint list | O(n) | O(n) | Already sorted, so no sort: copy before, absorb overlaps, copy after. |
| Max non-overlapping (activity selection) | O(n log n) | O(1)–O(n) | Sort by end, then one comparison per interval. |
| Max overlap: min-heap of end times | O(n log n) | O(n) | Sort, then each meeting does at most one poll and one offer at O(log n) each. |
| Max overlap: sweep over sorted starts/ends | O(n log n) | O(n) | Two sorts, then one linear merge-like walk. |
| Max overlap: difference array over range R | O(n + R) | O(R) | Two writes per interval, then one prefix-sum sweep over R slots. Best when R is small. |
| Free time of k people, N intervals in total | O(N log k) | O(k) | A heap holds each person's next interval: N polls and offers on a heap of size k. |
| Smallest interval per query (n intervals, q queries) | O(n log n + q log q) | O(n + q) | Sort both lists; each interval enters and leaves the heap once. |
06 · java
Raw vs Collections Framework
The overlap test: closed vs half-open
class Overlap { /** Closed intervals [s, e]: touching ends ([1,4] and [4,5]) share the point 4, so they overlap. */ static boolean closed(int[] a, int[] b) { return a[0] <= b[1] && b[0] <= a[1]; } /** Half-open [s, e) like meetings: [1,4) and [4,5) only touch, so they don't overlap. */ static boolean halfOpen(int[] a, int[] b) { return a[0] < b[1] && b[0] < a[1]; } /** The shared part of two closed intervals, or null if they don't meet. */ static int[] intersection(int[] a, int[] b) { int lo = Math.max(a[0], b[0]), hi = Math.min(a[1], b[1]); return lo <= hi ? new int[] {lo, hi} : null; }}- Two intervals overlap when each one starts before the other ends. Test that, never the four "cases" of how they can sit.
- Closed [s, e] (merging, balloons):
<=. Half-open [s, e) (meetings, bookings):<. - The shared part is
[max(starts), min(ends)], and it exists only when that start ≤ that end.
Sorting intervals: int[][] vs a record
class SortRaw { static void byStart(int[][] intervals) { Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); } static void byEnd(int[][] intervals) { // Never write (a, b) -> a[1] - b[1]: it overflows for values near ±2^31. Arrays.sort(intervals, (a, b) -> Integer.compare(a[1], b[1])); }}record Interval(int start, int end) {} class SortCollections { static List<Interval> byStartThenEnd(List<Interval> list) { List<Interval> copy = new ArrayList<>(list); copy.sort(Comparator.comparingInt(Interval::start).thenComparingInt(Interval::end)); return copy; }}- LeetCode hands you
int[][]. Sort it withArrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])). - Never write
(a, b) -> a[0] - b[0]when values can be near ±2³¹. The subtraction overflows and the sort silently goes wrong. LC 452 is built to catch exactly this. - In real code, an
Intervalrecord withComparator.comparingInt(...).thenComparingInt(...)reads better and can't mix up start and end. - Sorting
int[][]is sorting objects (each row is an array), so Java uses a stable merge sort (TimSort), not the dual-pivot quicksort it uses forint[].
Keep the most: activity selection
class ActivitySelection { /** Most intervals [start, end) you can keep with no two overlapping. Touching ends are fine. */ static int maxActivities(int[][] intervals) { int[][] sorted = intervals.clone(); Arrays.sort(sorted, (a, b) -> Integer.compare(a[1], b[1])); // earliest END first int count = 0, lastEnd = Integer.MIN_VALUE; for (int[] iv : sorted) { if (iv[0] < lastEnd) continue; // overlaps the last pick, so skip it count++; // fits, so take it lastEnd = iv[1]; } return count; }}- Sort by the key that makes the greedy choice obvious, keep one variable of state (
lastEnd), make one decision per interval. Integer.MIN_VALUEas the firstlastEndmeans "nothing kept yet", so the first interval always fits.iv[0] < lastEndtreats touching intervals ([1,2] and [2,3]) as compatible. Read the problem to see whether touching counts as overlap.
Counting overlaps: sorted arrays vs PriorityQueue
class Solution { public int minMeetingRooms(int[][] intervals) { int n = intervals.length; int[] starts = new int[n], ends = new int[n]; for (int i = 0; i < n; i++) { starts[i] = intervals[i][0]; ends[i] = intervals[i][1]; } Arrays.sort(starts); Arrays.sort(ends); int rooms = 0, e = 0; for (int s = 0; s < n; s++) { if (starts[s] < ends[e]) { // nobody has left yet rooms++; // open a new room } else { e++; // someone left: take over their room } } return rooms; }}class Solution { public int minMeetingRooms(int[][] intervals) { Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); // by start PriorityQueue<Integer> ends = new PriorityQueue<>(); // end times of rooms in use for (int[] m : intervals) { if (!ends.isEmpty() && ends.peek() <= m[0]) { // earliest-free room is free by now ends.poll(); // reuse it } ends.offer(m[1]); // this meeting occupies a room until m[1] } return ends.size(); // rooms ever needed at once }}PriorityQueue<Integer>is a min-heap by default.peek()is O(1);offerandpollare O(log n).- The heap version also tells you which room frees up first. That matters for follow-ups like LC 2402 Meeting Rooms III.
- The sweep version uses primitive
int[]: no boxing and very cache-friendly. It is often faster in practice.
Range counting: difference array vs TreeMap
class Solution { public boolean carPooling(int[][] trips, int capacity) { int[] change = new int[1001]; // difference array over the road for (int[] t : trips) { change[t[1]] += t[0]; // they get in at "from" change[t[2]] -= t[0]; // and out at "to" } int inCar = 0; for (int km = 0; km <= 1000; km++) { // sweep left to right inCar += change[km]; if (inCar > capacity) return false; } return true; }}class Solution { public boolean carPooling(int[][] trips, int capacity) { TreeMap<Integer, Integer> change = new TreeMap<>(); // only the points where something happens for (int[] t : trips) { change.merge(t[1], t[0], Integer::sum); change.merge(t[2], -t[0], Integer::sum); } int inCar = 0; for (int delta : change.values()) { // ascending location order inCar += delta; if (inCar > capacity) return false; } return true; }}- Small coordinates (≤ 10⁶)? Use a plain
int[]difference array: O(n + range), no sorting. - Huge or sparse coordinates (up to 10⁹)? A
TreeMap<Integer, Integer>keeps only the points where something changes.merge(key, delta, Integer::sum)adds to it in one line. - Iterating a
TreeMap'svalues()visits keys in increasing order, which is exactly the sweep.
| call | does | cost |
|---|---|---|
Arrays.sort(int[][] a, Comparator) | Stable sort of the rows (TimSort) | O(n log n) |
Integer.compare(x, y) | Overflow-safe comparison for comparators | O(1) |
Comparator.comparingInt(f).thenComparingInt(g) | Sort by one key, break ties by another | O(1) per compare |
new PriorityQueue<Integer>() | Min-heap (use Comparator.reverseOrder() for max) | O(1) to build |
pq.offer(x) / pq.poll() / pq.peek() | Insert / remove the smallest / look at it | O(log n) / O(log n) / O(1) |
treeMap.merge(k, v, Integer::sum) | Add a +/− event at point k | O(log n) |
treeMap.ceilingEntry(x) | Smallest key ≥ x (or null) | O(log n) |
Integer[] order + Arrays.sort(order, cmp) | Sort query positions by value, keeping the original order | O(q log q) |
list.toArray(new int[0][]) | Turn a List<int[]> into the int[][] LeetCode expects | O(n) |
Merge or insert intervals
→ Sort by start + List<int[]>
Overlapping intervals end up next to each other.
Keep the most non-overlapping intervals / fewest removals / fewest arrows
→ Sort by end + lastEnd
The earliest finisher is always a safe pick (exchange argument).
Max number of simultaneous intervals
→ Min-heap of ends, or a sweep over sorted starts/ends
Both O(n log n). The heap also tells you which resource frees up first.
Overlap counts on a small coordinate range
→ int[] difference array
O(n + range) with no sorting.
Overlap counts on huge or sparse coordinates
→ TreeMap of +/− events
Stores only the points where something changes.
Common free time of several people
→ Merge everyone's busy intervals (or a heap of each person's next one)
Free time is just the gaps between merged busy blocks.
Many point queries over many intervals
→ Sort queries + intervals, sweep with a heap
Each interval enters and leaves the heap once.
07 · recognise
Spot the pattern
"Merge", "insert", "union of ranges"
Sort by start, extend the last group
"Maximum number of non-overlapping …", "minimum removals so nothing overlaps"
Sort by end, keep what fits (activity selection)
"Minimum rooms / platforms / cars", "max concurrent", "capacity at any time"
Min-heap of end times, sweep line, or difference array
"Minimum arrows / points to cover all intervals"
Sort by end, place the point at the earliest end
"When is everyone free?"
Merge all busy intervals; the gaps are the answer
"For each query point, the best interval containing it"
Sort the queries too (offline), sweep with a heap
Sorted unique numbers to describe as ranges
Stretch each run while the next number is one more
08 · traps & tricks
Mistakes to avoid, tricks to use
traps
- Sorting by the wrong key. Sorting by start (or by length) breaks activity selection: [1,10], [2,3], [4,5].
- Comparator overflow:
a[1] - b[1]breaks for values near ±2³¹. UseInteger.compare. - Getting "touching" wrong. LC 56 merges [1,4] and [4,5]. LC 435 allows [1,2] and [2,3] together. LC 452 bursts both [1,2] and [2,3] with one arrow at 2.
- Merge: writing
last[1] = iv[1]instead ofMath.max(last[1], iv[1]). An interval fully inside the group would shrink it. - Meeting Rooms II:
peek() < startinstead of<=gives back-to-back meetings two rooms. - Car Pooling: subtracting at
to + 1. Passengers leave atto, so the seat is free for someone boarding there. - LC 1851: sorting the
queriesarray itself and losing where each answer belongs. - Mutating the caller's array when sorting. Clone it first if the input must stay unchanged.
tricks
- Draw the intervals as bars on a number line. Overlaps and the right sort order jump out.
- Ask two questions before coding: which key do I sort by, and do touching intervals overlap in this problem?
- Edge cases to test: one interval, identical intervals, nested intervals, touching ends, negative or extreme coordinates.
- For "how many at once" questions, mention both the heap and the sweep, then code the one you're faster at.
- Chalo, dry-run karte hain: run your loop on three intervals by hand before typing. Most interval bugs are one
<or one missingmax.
09 · why & how
Questions you might be too shy to ask
Should I sort by start or by end?
Sort by end when you're choosing intervals to keep, like activity selection, LC 435 and LC 452. The earliest end leaves the most room. Sort by start when you're combining or sweeping, like merge, insert, meeting rooms and free time. Overlapping intervals then sit next to each other.
Why not pick the shortest interval first?
Shortest-first can block two others. Take [1,5], [4,7], [6,10]. The shortest is [4,7] (length 3), and it overlaps both of the others, so you keep only 1. Earliest-end keeps [1,5] and [6,10], which is 2. Earliest-start fails too: [1,10], [2,3], [4,5].
Do touching intervals overlap?
It depends on the problem, so read it carefully. Merge Intervals (LC 56) treats [1,4] and [4,5] as overlapping. Non-overlapping Intervals (LC 435) treats [1,2] and [2,3] as fine together. Meeting rooms treat [5,10] and [10,15] as able to share a room. Balloons (LC 452) are closed, so one arrow at x = 2 bursts both [1,2] and [2,3]. One < vs <= decides it.
Merge uses iv[0] > last[1] but LC 435 uses iv[0] < lastEnd. Why does one say > and the other <?
They ask opposite questions. Merge asks "is there a gap?": a new group starts only when the start is strictly after the end, so touching [1,4] and [4,5] merge. LC 435 asks "is there a clash?": a clash only when the start is strictly before the last end, so touching [1,2] and [2,3] are fine. Dhyan do: decide the touching rule first, then the sign writes itself.
I wrote last[1] = ... but never put last back into the list. How does merged change?
An int[] is an object. merged.get(...) hands you a reference to the same array that sits inside the list, not a copy. So last[1] = 7 edits the array the list already holds. Nothing to put back. That's also why we add new int[] {iv[0], iv[1]}: a fresh copy, so stretching a group never edits the caller's input row.
What is new int[0][] in merged.toArray(new int[0][])?
It only tells Java the type you want back: an int[][]. The empty array is too small, so toArray creates a new one of exactly the right size and fills it. Without the argument, toArray() returns Object[], which you can't return as int[][].
My intervals are objects like Interval with start and end, not int[][]. How do I sort them?
Same idea, different syntax. For a List<Interval>: list.sort(Comparator.comparingInt(iv -> iv.start)). For an Interval[]: Arrays.sort(arr, Comparator.comparingInt(iv -> iv.start)). Employee Free Time hands you objects exactly like this.
For Insert Interval, can't I just add the new one and call my merge code?
Yes, and it's correct: add it, sort, merge. That's O(n log n). But the list is already sorted and disjoint, so the copy–absorb–copy walk does it in O(n) with no sort. Say the simple version first if you like, then give the O(n) one — that is what the interviewer is waiting for.
Heap or sweep line for Meeting Rooms II?
Both are O(n log n) and both are accepted. The sweep line is shorter and uses primitive arrays. The heap matches the story ("rooms with end times") and extends to follow-ups that ask which room to use. Know one well and mention the other.
Why does the Meeting Rooms II heap hold end times, not start times?
The only question at each new meeting is "is some room free by now?". A room becomes free at its meeting's end. The smallest end in the heap is the room that frees up first, so one peek() answers it. Start times of running meetings don't help decide anything.
In the heap version, why if and one poll(), not a while loop that frees every finished room?
The new meeting needs only one room, so freeing one free room is enough. With if, the heap never shrinks: its size only grows when no room was free. So ends.size() at the end is the peak number of rooms. A while loop is also correct, but then the heap can shrink, and you must track max(size) yourself.
What exactly is a "sweep line"?
Picture a vertical line moving left to right over the number line. It only stops at events (starts and ends), in sorted order, and keeps a running state such as "how many intervals are open". Nothing changes between two events, so you skip that stretch. Sorting the events costs O(n log n); the walk is O(n).
LC 1851 answers the queries in a different order. Isn't that cheating?
No. It's called answering offline: all queries are known up front, so you may handle them in any order, as long as each answer goes back to its original position. That's why we sort an array of indices, not the queries themselves.
The interviewer gives arrival[] and departure[] as two separate arrays (minimum railway platforms). What changes?
Nothing important. It's Meeting Rooms II with trains. Sort both arrays on their own and run the sweep: an arrival before the earliest unused departure needs a new platform. Splitting the pairs is fine because you only count, you never ask which train uses which platform. Ask one thing first: can a train arrive at the same minute another one leaves and use that platform?
Meeting Rooms and Employee Free Time are LeetCode Premium. How do I practise them?
Right here: the statement, the code runner and the judge on this page are free. The linked LintCode twins practise the same idea; their input format differs a little (Interval objects, or flattened arrays).
10 · practice
Interview problems
Every problem has brute → better → optimal solutions in Java, with complexity and a dry run.
- #228Summary RangesEasyNetflixGoogleMeta
- #252
- #56
- #57
- #435
- #452Minimum Number of Arrows to Burst BalloonsMediumMicrosoftAmazonGoogle
- #253
- #1094Car PoolingMediumMetaAmazon
- #759
- #1851Minimum Interval to Include Each QueryHardGoogle
Also practise this here
Each problem has one home page in the course; these use this chapter's idea too. The note says what to look for.
- #729My Calendar IMediumin BST
Intervals arriving one by one: a TreeMap's floor and ceiling neighbours give the overlap test in O(log n).
- #853
- #23
11 · revise
The whole chapter on one screen
9 cards, about a minute. Read them the night before an interview, or right after the chapter to lock it in.
- what it is
An interval is [start, end]. Sort first (by start to merge or sweep, by end to keep the most), then one pass decides each interval once.
- use it when
"Merge", "insert", "overlap", "rooms needed", "free time", "remove the fewest so none overlap", "capacity along a route".
- template
Sort by start; if
cur[0] > last[1]open a new group, elselast[1] = Math.max(last[1], cur[1]). - template
Rooms: min-heap of ends.
if (!pq.isEmpty() && pq.peek() <= s) pq.poll(); pq.offer(e);The heap's size is the answer. - cost
O(n log n) for the sort, O(n) for the sweep, O(log n) per heap step. A difference array is O(n + range).
- trap
Touching rules differ: [1,4]+[4,5] merge in LC 56, but [1,2] and [2,3] live together in LC 435 and meeting rooms. One
<vs<=. - trap
(a, b) -> a[1] - b[1]overflows near ±2³¹ and silently mis-sorts (LC 452). UseInteger.compare. - trap
Merging with
last[1] = cur[1]shrinks the group on nested intervals like [1,10], [2,3]. Always take the max. - pro tip
Draw the intervals as bars on a number line first. The sort key and the overlap rule jump out.
12 · recall
Flip, remember, repeat
Write the overlap test for closed [a,b] and [c,d], and for half-open meetings.
Question 1: Write the overlap test for closed [a,b] and [c,d], and for half-open meetings.
13 · check yourself
Quick quiz
To keep the MOST non-overlapping intervals, which sort order makes greedy correct?
Merge Intervals: after sorting by start, the current interval is [5, 7] and the last group is [1, 6]. What happens?
Meetings [5, 10) and [10, 15). Can one person attend both?
Insert [4, 8] into [[1,2],[3,5],[6,7],[8,10],[12,16]]. Which intervals get absorbed?
Meeting Rooms II (heap): the heap holds ends {10, 15}. The next meeting is [10, 12]. What does the heap look like afterwards?
Why is `(a, b) -> a[1] - b[1]` dangerous in LC 452?
LC 1851: why can an interval popped from the heap (right < q) be thrown away for good?
14 · learn more
A second teacher, if you want one
- ▶ videoMerge Overlapping Intervals | Brute, Optimal with Precise TC analysis ↗Striver (take U forward) · EnglishMerge Intervals from brute force to sort-and-sweep, with a careful time-complexity analysis.
- ▶ playlistLine Sweep Technique: Concepts & Questions ↗codestorywithMIK · HindiLine sweep from scratch, then Meeting Rooms II, Car Pooling and My Calendar. This is the next step after merging intervals.
- ▶ videoL10. Minimum number of platforms required in a railway station ↗Striver (take U forward) · EnglishSort arrivals and departures, sweep, and count the overlap. It's the same problem as Meeting Rooms II, set at a railway station.