AlgoMaster Logo

Meeting Rooms III

hardFrequencyUpdated September 21, 2026

Understanding the Problem

We have n rooms and a list of meetings, each with a start and end time. We need to simulate a scheduling process: meetings are processed in order of their start time, each gets assigned to the lowest-numbered available room, and if no room is free, the meeting waits for the earliest room to open up.

The part that needs care is the delay rule. When a meeting can't start on time, it waits until a room frees up, but it keeps its original duration. A meeting originally scheduled for [2, 7] (duration 5) that gets delayed to start at time 10 would end at time 15.

After all meetings are scheduled, we report which room hosted the most meetings. If there's a tie, return the smallest room number.

The work, then, is to track which rooms are free and which are busy, and to quickly find the next room that becomes available.

Key Constraints:

  • 1 <= n <= 100 -- The number of rooms is small. Even O(n) scans per meeting are cheap.
  • 1 <= meetings.length <= 10^5 -- We could have up to 100,000 meetings. This is the dimension that matters for time complexity.
  • 0 <= starti < endi <= 5 * 10^5 -- Time values can be large, but we don't need to iterate over every time unit. Be careful with integer overflow when meetings are delayed repeatedly.

Approach 1: Brute Force Simulation

Intuition

Maintain an array tracking when each room becomes free. For each meeting, processed in start-time order, scan all rooms to find the best assignment.

If at least one room is free (its end time <= meeting's start time), pick the free room with the lowest index. If no room is free, find the room that becomes free earliest (lowest end time, breaking ties by room index), delay the meeting to start when that room opens, and adjust the end time accordingly.

Algorithm

  1. Sort meetings by start time.
  2. Create an array roomEndTime of size n, initialized to 0 (all rooms start free).
  3. Create an array count of size n to track how many meetings each room hosts.
  4. For each meeting [start, end]:
    • Scan all rooms. Find the room with the earliest end time. If that end time <= start, it's a free room. Among all free rooms, pick the one with the lowest index.
    • If no room is free, pick the room with the smallest end time (lowest index to break ties). The meeting starts at that room's end time, and the new end time is roomEndTime[room] + (end - start).
    • Update roomEndTime[room] and increment count[room].
  5. Return the room index with the highest count (lowest index to break ties).

Visualization and Code

Loading animation...

For each meeting, we scan all n rooms to find the best one. Since n is at most 100, this is fast enough to pass. To remove the per-meeting scan, the next approach replaces the linear search with two heaps that surface the room we need in O(log n).

Approach 2: Sorting + Two Min-Heaps

Intuition

Split the rooms into two groups: available rooms and busy rooms, each in its own min-heap. The available heap is ordered by room number, so its top is always the lowest-numbered free room. The busy heap is ordered by (end time, room number), so its top is always the room that frees up first.

For each meeting, first move rooms from the busy heap back to the available heap if their end time has passed. Then assign the meeting to the lowest-numbered free room, or, if none is free, delay it onto the earliest-ending busy room.

Algorithm

  1. Sort meetings by start time.
  2. Initialize an available min-heap with rooms 0 through n-1 (sorted by room number).
  3. Initialize an empty busy min-heap (sorted by end time, then room number).
  4. Create a count array of size n.
  5. For each meeting [start, end]:
    • Move all rooms from the busy heap where endTime <= start back to the available heap.
    • If the available heap is non-empty, pop the smallest room number and assign the meeting there.
    • If the available heap is empty, pop the room with the earliest end time from the busy heap. The meeting starts at that end time: new end = poppedEndTime + (end - start).
    • Push the assigned room with its new end time onto the busy heap. Increment count[assignedRoom].
  6. Return the room with the highest count (lowest index for ties).

Visualization and Code

Loading animation...

The two-heap version is the standard solution: it drops the per-meeting scan to O(log n) while keeping the same sorted-by-start-time simulation that makes the assignment rules correct.