Find the Most Frequently Used Meeting Room
Company: Amazon
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Technical Screen
## Find the Most Frequently Used Meeting Room
### Problem
Implement `mostBookedRoom(roomCount, meetings) -> roomId`.
Rooms are numbered `0` through `roomCount - 1`. Process meetings in increasing original start time. For each half-open meeting `[start, end)`:
1. If one or more rooms are free at `start`, assign the smallest-numbered free room and keep the original interval.
2. Otherwise delay the meeting until the earliest room becomes free, preserving its duration `end - start`. If several rooms become free at that earliest time, use the smallest room ID.
Return the room that hosted the most meetings. Break a usage-count tie by the smallest room ID.
### Portable Contract
- `1 <= roomCount <= 10,000`.
- `meetings` is a JSON array of two-integer arrays `[start, end]`, with `1 <= meetings.length <= 12,000`.
- Original start times are distinct.
- `0 <= start < end <= 9,000,000,000,000`.
- Inputs guarantee every delayed end time is at most `9,007,199,254,740,991`, so it remains exact in signed 64-bit and JavaScript integer arithmetic.
- Do not modify `meetings`.
- Let `B` be the compact UTF-8 JSON byte length of `[roomCount,meetings]`, counting every structural and numeric byte. Inputs satisfy `B <= 160,000`; the returned room ID adds at most five serialized bytes.
- Target `O(m log m + m log roomCount)` time and `O(m + roomCount)` auxiliary space for `m = meetings.length`.
Python and JavaScript use ordinary numbers and arrays. Java may use `int` plus `List<List<Long>>`, and C++ may use `int` plus `vector<vector<long long>>`; return an integer room ID.
```hint Track two different orderings
Choosing an immediately available room and choosing the room that becomes available next require different keys.
```
```hint Release before assigning
Before handling a meeting, move every room whose current end time is no later than that meeting's original start into the available state.
```
### Examples
```text
roomCount = 2
meetings = [[0, 10], [1, 5], [2, 7], [3, 4]]
roomId = 0
```
```text
roomCount = 3
meetings = [[1, 20], [2, 10], [3, 5], [4, 9], [6, 8]]
roomId = 1
```
### Discussion Requirements
- Explain why meetings are considered by original start time even after some are delayed.
- Identify the keys used for available rooms and occupied rooms.
- Show how preserving duration can require 64-bit end-time arithmetic.
- Test simultaneous releases, repeated delays, usage-count ties, and one-room input.
Quick Answer: Simulate room assignment for meetings that may be delayed, then identify the room used most often under explicit tie-breakers. It tests event ordering, duration preservation, dual priority rules, large timestamps, and careful scheduling state.
Implement `mostBookedRoom(roomCount, meetings) -> roomId`.
Rooms are numbered `0` through `roomCount - 1` and all of them are free before any
meeting begins. Meetings are considered in increasing **original** start time, no
matter how the input array happens to be ordered and no matter how far a meeting is
later delayed. Each meeting occupies its room over the half-open interval
`[start, end)`, so a room whose current end time is **less than or equal to** the
next meeting's original start is free again for that meeting.
For each meeting `[start, end)`, in original-start order:
1. If one or more rooms are free at `start`, assign the **smallest-numbered** free
room and keep the meeting's original interval `[start, end)`.
2. Otherwise, delay the meeting until the earliest time some room becomes free,
preserving its duration `end - start`. A meeting delayed to time `t` occupies
`[t, t + (end - start))`. If several rooms become free at that same earliest
time, use the **smallest room ID** among them.
Return the ID of the room that hosted the most meetings. If several rooms are tied
for the highest count, return the **smallest** such room ID. The answer is a single
integer and is uniquely determined for every valid input.
`meetings` must not be modified.
### Constraints
- `1 <= roomCount <= 10,000`.
- `meetings` is an array of two-integer arrays `[start, end]`, with
`1 <= meetings.length <= 12,000`. There is no empty-`meetings` case.
- Original start times are distinct.
- `0 <= start < end <= 9,000,000,000,000`.
- Inputs guarantee every delayed end time is at most `9,007,199,254,740,991`, so it
remains exact in signed 64-bit and JavaScript integer arithmetic.
- Let `B` be the compact UTF-8 JSON byte length of `[roomCount, meetings]`, counting
every structural and numeric byte. Inputs satisfy `B <= 160,000`; the returned room
ID adds at most five serialized bytes.
- Target `O(m log m + m log roomCount)` time and `O(m + roomCount)` auxiliary space
for `m = meetings.length`.
End times reach `9,000,000,000,000`, which is far beyond `2^31 - 1`, and delayed end
times grow larger still. Java must therefore hold meeting times in `long` and C++ in
`long long`; `roomCount` and the returned room ID both fit in `int`. Python and
JavaScript use ordinary numbers and arrays: every value stays at or below
`9,007,199,254,740,991 = 2^53 - 1`, so JavaScript integer arithmetic remains exact.
### Example 1
```text
roomCount = 2
meetings = [[0, 10], [1, 5], [2, 7], [3, 4]]
roomId = 0
```
Room 0 takes `[0, 10)` and room 1 takes `[1, 5)`. Meeting `[2, 7)` finds no free room,
so it waits for room 1 (free first, at time 5) and runs `[5, 10)`. Meeting `[3, 4)`
then finds rooms 0 and 1 both free at time 10, takes the smaller ID 0, and runs
`[10, 11)`. Each room hosted two meetings, so the count ties and the smaller ID wins.
### Example 2
```text
roomCount = 3
meetings = [[1, 20], [2, 10], [3, 5], [4, 9], [6, 8]]
roomId = 1
```
Rooms 0, 1 and 2 take `[1, 20)`, `[2, 10)` and `[3, 5)`. Meeting `[4, 9)` waits for
room 2 (free at 5) and runs `[5, 10)`. Meeting `[6, 8)` then waits for room 1 (free at
10, ahead of room 2's 10 only by the smaller room ID) and runs `[10, 12)`. Rooms 1 and
2 each hosted two meetings, so the tie resolves to room 1.
Constraints
- 1 <= roomCount <= 10,000
- 1 <= meetings.length <= 12,000 (there is no empty-meetings case)
- meetings[i] = [start, end] with 0 <= start < end <= 9,000,000,000,000
- Original start times are distinct
- Inputs guarantee every delayed end time is at most 9,007,199,254,740,991, so it remains exact in signed 64-bit and JavaScript integer arithmetic
- meetings must not be modified
- Let B be the compact UTF-8 JSON byte length of [roomCount, meetings], counting every structural and numeric byte. Inputs satisfy B <= 160,000; the returned room ID adds at most five serialized bytes
- Target O(m log m + m log roomCount) time and O(m + roomCount) auxiliary space for m = meetings.length
- End times exceed 2^31 - 1, so Java must use long and C++ long long for meeting times; roomCount and the returned room ID fit in int
Examples
Input: (1, [[0, 1]])
Expected Output: 0
Explanation: The only meeting takes the only room, so room 0 hosts every meeting.
Input: (2, [[0, 10], [1, 5], [2, 7], [3, 4]])
Expected Output: 0
Explanation: Rooms 0 and 1 each host two meetings, so the smaller room id 0 wins the tie.
Hints
- Track two different orderings. Choosing an immediately available room and choosing the room that becomes available next require different keys.
- Release before assigning. Before handling a meeting, move every room whose current end time is no later than that meeting's original start into the available state.
- A delayed meeting keeps its duration, not its original end time, so end values grow past what a 32-bit integer can hold -- decide your integer width before you write the loop.