Skip to content

Intermediate: core algorithms · Heaps and greedy algorithms · topic 39 of 61 · 40 min

Interval problems

Explanation

An interval is a pair (start, end), like a meeting, a booking or a train's stay at a station. Most interval problems start by sorting, by start time to merge overlaps or by end time to keep as many as possible. Then one pass, sometimes with a heap of end times, answers questions such as "merge these slots", "how many rooms do we need?" and "how many platforms does this station need?".

Intervals and overlap

An interval [start, end] covers every time from start to end. Two intervals a and b overlap when a.start ≤ b.end and b.start ≤ a.end. The tricky part is the edges: do [1, 4] and [4, 5] overlap? For merging free time slots we usually say yes (they touch, so they join into [1, 5]); for meetings that may run back to back we usually say no. Always ask, and write the comparison (< or ≤) to match.

Without sorting, checking every pair is O(n²). After sorting by start time, any interval can only overlap the ones near it in the list, so one pass is enough: O(n log n) for the sort plus O(n).

Merge overlapping intervals

Sort by start. Walk through; if the current interval starts at or before the end of the last merged one, extend that end (take the max, because the current one may be fully inside). Otherwise start a new merged interval.

python
def merge(intervals):
    merged = []
    for start, end in sorted(intervals):
        if merged and start <= merged[-1][1]:
            merged[-1][1] = max(merged[-1][1], end)
        else:
            merged.append([start, end])
    return merged

print(merge([[8, 10], [1, 3], [2, 6], [15, 18], [6, 7]]))   # Output: [[1, 7], [8, 10], [15, 18]]
Touching intervals such as [2, 6] and [6, 7] join here because the test is start <= end.

Insert an interval into a sorted list

When the list is already sorted and non-overlapping, inserting a new interval does not need a full sort. Copy every interval that ends before the new one starts; then absorb every interval that starts before the new one ends, widening the new interval; then copy the rest. That is O(n).

python
def insert(intervals, new):
    result, i, n = [], 0, len(intervals)
    start, end = new
    while i < n and intervals[i][1] < start:      # completely before
        result.append(intervals[i])
        i += 1
    while i < n and intervals[i][0] <= end:       # overlapping: absorb
        start = min(start, intervals[i][0])
        end = max(end, intervals[i][1])
        i += 1
    result.append([start, end])
    result.extend(intervals[i:])                   # completely after
    return result

print(insert([[1, 2], [3, 5], [6, 7], [8, 10], [12, 16]], [4, 8]))   # Output: [[1, 2], [3, 10], [12, 16]]

Minimum meeting rooms

How many rooms are needed so every meeting gets one? Sort meetings by start. Keep a min-heap of the END times of meetings currently using a room. For each meeting, if the earliest-ending room is already free (its end ≤ this start), reuse it with heapreplace; otherwise open a new room. The heap size at the end is the answer: O(n log n). Another way sorts all starts and all ends separately and walks them with two pointers, counting how many meetings are running at once.

python
import heapq

def min_rooms(meetings):
    ends = []
    for start, end in sorted(meetings):
        if ends and ends[0] <= start:
            heapq.heapreplace(ends, end)     # reuse the room that frees first
        else:
            heapq.heappush(ends, end)        # open a new room
    return len(ends)

print(min_rooms([(0, 30), (5, 10), (15, 20)]), min_rooms([(1, 5), (5, 8)]))   # Output: 2 1

Railway platforms: the classic Indian question

A station has the arrival and departure times of every train for one day, written as numbers such as 900 for 9:00 and 1120 for 11:20 (comparing them as numbers works within one day). How many platforms are needed so no train waits? This is the meeting-rooms question again. Sort the arrivals and the departures SEPARATELY. Walk both lists: when the next event is an arrival, one more train is on a platform; when it is a departure, one fewer. The largest count seen is the answer.

The edge rule matters. The usual version of this question says that if a train arrives at exactly the time another departs, the arriving train needs a NEW platform (the leaving train is still standing there). So an arrival is processed before a departure at the same time: compare with arrival <= departure.

python
def min_platforms(arr, dep):
    arr, dep = sorted(arr), sorted(dep)
    i = j = 0
    on_platform = best = 0
    while i < len(arr):
        if arr[i] <= dep[j]:          # equal time: the arrival needs its own platform
            on_platform += 1
            best = max(best, on_platform)
            i += 1
        else:
            on_platform -= 1
            j += 1
    return best

print(min_platforms([900, 940, 950, 1100, 1500, 1800], [910, 1200, 1120, 1130, 1900, 2000]))   # Output: 3
Between 11:00 and 11:20 three trains are at the station at once.

Fewest intervals to remove

To make the rest non-overlapping with the fewest removals, keep as many intervals as possible: that is activity selection again (Topic 3). Sort by END, keep each interval that starts at or after the last kept end, and count the others as removed. Touching intervals such as [1, 2] and [2, 3] do not overlap here.

Common mistakes

  • Forgetting to sort first, or sorting by the wrong key. Merge: by start. Keep the most: by end.
  • Setting merged[-1][1] = end instead of max(...). An interval inside another, like [1, 10] then [2, 3], would shrink it.
  • Getting the touching rule wrong. Fix: ask, then use < or <= on purpose, and test with a pair that touches.
  • In JavaScript, sorting with arr.sort() and no compare function. It sorts as strings, so 10 comes before 9. Fix: arr.sort((a, b) => a[0] - b[0]).
  • In the platform problem, pairing each sorted arrival with the sorted departure at the same index as if they were the same train. Fix: the two lists are just events; only the counts matter.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Interval problems · 1/8

Interval problems

This lesson covers interval problems: merging, inserting, rooms, platforms and removals.

Prefer a video by a teacher? Find free videos on “merge intervals meeting rooms minimum platforms railway station interval scheduling” on YouTube ↗

In real life: Platforms at a busy junction

Railway planners must know the peak number of trains at a station at once to assign platforms. With each day's timetable, sorting the arrival and departure times and sweeping through them gives that peak. The same sweep tells a hospital how many operating theatres to staff, and tells a co-working space how many meeting rooms it needs at the busiest hour.

python
arrivals   = [600, 615, 630, 700, 705, 720]
departures = [625, 640, 710, 715, 730, 740]
events = sorted([(t, 0) for t in arrivals] + [(t, 1) for t in departures])
now = peak = 0
for time, kind in events:
    now += 1 if kind == 0 else -1
    peak = max(peak, now)
print(peak)
Shows 3. Arrivals (kind 0) sort before departures (kind 1) at the same time, which matches the "needs a new platform" rule.

Practice (0/4 done)

Task 1 · Code · Python

Write merge_intervals(intervals) where intervals is a list of [start, end] pairs (start ≤ end) in any order. Merge all overlapping intervals and return them as a list of [start, end] lists sorted by start. Intervals that only touch, like [1, 4] and [4, 5], DO merge. Example: merge_intervals([[1, 3], [2, 6], [8, 10], [15, 18]]) returns [[1, 6], [8, 10], [15, 18]].

Task 2 · Code · Python

A station has trains with arrival times arrivals[i] and departure times departures[i] (train i), written as integers like 900 for 9:00 and 1120 for 11:20, all within one day, with departures[i] ≥ arrivals[i]. Write min_platforms(arrivals, departures) that returns the minimum number of platforms so that no train waits. RULE: if a train arrives at exactly the same time as another departs, the arriving train needs a NEW platform. No trains means 0. Example: arrivals [900, 940, 950, 1100, 1500, 1800] and departures [910, 1200, 1120, 1130, 1900, 2000] give 3.

Task 3 · Code · Python

Write erase_overlap_intervals(intervals) that returns the MINIMUM number of intervals to remove so that the remaining ones do not overlap. Intervals that only touch, like [1, 2] and [2, 3], do NOT overlap. Use the greedy rule: sort by end and keep as many as possible. Example: erase_overlap_intervals([[1, 2], [2, 3], [3, 4], [1, 3]]) returns 1.

Task 4 · Code · Javascript

In JavaScript, write mergeIntervals(intervals) where intervals is an array of [start, end] pairs in any order. Return a NEW array of merged intervals sorted by start; touching intervals like [1, 4] and [4, 5] merge. Do not change the input array or its pairs. Careful: arr.sort() with no compare function sorts numbers as strings.

Quick quiz

Question 1

1.Why sort intervals by start before merging?

Question 2

2.Merging [1, 10] and then [2, 3]: what goes wrong if you set the end to the new end instead of the max?

Question 3

3.In the minimum meeting rooms solution, what does the min-heap store?

Question 4

4.Trains: arrivals [1000, 1015] and departures [1015, 1030]. With the rule "arriving when another departs needs a new platform", how many platforms?

Question 5

5.For the fewest removals to make intervals non-overlapping, sort by…

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Why sort intervals by start before merging?

Answer: So an interval can only overlap the ones right before it, and one pass is enough

After sorting, each interval only needs to be compared with the last merged one.

Merging [1, 10] and then [2, 3]: what goes wrong if you set the end to the new end instead of the max?

Answer: The result becomes [1, 3], losing part of [1, 10]

The inner interval ends earlier, so the merged end must stay max(10, 3) = 10.

In the minimum meeting rooms solution, what does the min-heap store?

Answer: End times of meetings currently using a room

The root is the room that frees up first; if it is free by the next start, that room is reused.

Trains: arrivals [1000, 1015] and departures [1015, 1030]. With the rule "arriving when another departs needs a new platform", how many platforms?

Answer: 2

At 10:15 the first train is still there as the second arrives, so both need a platform.

For the fewest removals to make intervals non-overlapping, sort by…

Answer: end time

Keeping the most intervals is activity selection, which sorts by end time.

For the most non-overlapping meetings in one room, sort by…Related

Answer: end time

The meeting that ends first leaves the most room for the rest; the exchange argument proves it.

From Greedy algorithms: the idea

Why is the waiting list numbered with PARTITION BY train_no, journey_date, class_code?Related

Answer: Each train, date and class has its own separate queue

A 3A waiting list on one date has nothing to do with Sleeper or another date.

From Project: a railway booking database (IRCTC-like)

Merging k sorted lists with N values in total using a heap costs…Related

Answer: O(N log k)

The heap holds at most k items, and each of the N values is pushed and popped once.

From Heap patterns: top-k and streams

A question says "n ≤ 15 tasks, assign each worker a different task, minimise the total cost". Which DP pattern fits?Related

Answer: Bitmask DP over the set of used tasks

The state needs to know which tasks are already used; with n ≤ 15 there are only 2¹⁵ = 32,768 sets.

From More DP patterns and how to spot them

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Heaps and greedy algorithms” before its exam: More greedy classics.
  2. Module 8 exam: Heaps and greedy algorithms · 15 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Graphs. 61 topics left in the course before the final exam.

← Previous: Greedy algorithms: the idea