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.
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.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.
roomEndTime of size n, initialized to 0 (all rooms start free).count of size n to track how many meetings each room hosts.[start, end]:roomEndTime[room] + (end - start).roomEndTime[room] and increment count[room].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).
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.
Rule 3 says that when a room frees up, the waiting meeting with the earlier original start time gets it. Processing meetings in sorted start-time order satisfies this without extra bookkeeping: a meeting is only ever assigned after every meeting with an earlier start has already been placed, so the room it receives was never owed to an earlier meeting. The two heaps hold all n rooms between them at every step, so a room is either free or busy, never lost or double-counted.
[start, end]:endTime <= start back to the available heap.poppedEndTime + (end - start).count[assignedRoom].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.