There are n rooms numbered from 0 to n - 1. You are given a 2D integer array meetings where meetings[i] = [start[i], end[i]] means that a meeting will be held during the half-closed time interval [start[i], end[i]). All the values of start[i] are unique.
Meetings are allocated to rooms in the following manner:
Each meeting will take place in the unused room with the lowest number.
If there are no available rooms, the meeting will be delayed until a room becomes free. The delayed meeting should have the same duration as the original meeting.
When a room becomes unused, meetings that have an earlier original start time should be given the room.
Return the number of the room that held the most meetings. If there are multiple rooms, return the room with the lowest number.
A half-closed interval [a, b) is the interval between a and b including a and not including b.
Example 1:
Input: n = 2, meetings = [[1,10],[2,10],[3,10],[4,10]]
Output: 0Explanation:
The room with most meetings held and have lowest number is 0.
Example 2:
Input: n = 3, meetings = [[1,20],[2,10],[3,5],[6,8],[4,9]]
Output: 1Explanation:
Room 0 held 1 meeting while rooms 1 and 2 each held 2 meetings, so we return 1 as it is lowest.
Constraints:
1 <= n <= 1001 <= meetings.length <= 100,000meetings[i].length == 20 <= start[i] < end[i] <= 500,000start[i] are unique.Before attempting this problem, you should be comfortable with:
Meetings must be processed in order of their start times. For each meeting, we check rooms in order from 0 to n - 1. If a room is free by the meeting's start time, we assign the meeting there. Otherwise, we find the room that becomes free earliest and delay the meeting until that room is available. We track how many meetings each room hosts and return the room with the most meetings, breaking ties by smallest room number.
rooms (end times) and meeting_count, both of size n.(start, end):0 to n - 1. If rooms[i] <= start, assign the meeting: set rooms[i] = end, increment meeting_count[i], and move to the next meeting.min_room as the room with the earliest end time.min_room: set rooms[min_room] += (end - start) and increment meeting_count[min_room].class Solution:
def mostBooked(self, n: int, meetings: List[List[int]]) -> int:
meetings.sort()
rooms = [0] * n # end time of meetings in rooms
meeting_count = [0] * n
for s, e in meetings:
min_room = 0
found = False
for i in range(n):
if rooms[i] <= s:
found = True
meeting_count[i] += 1
rooms[i] = e
break
if rooms[min_room] > rooms[i]:
min_room = i
if found:
continue
meeting_count[min_room] += 1
rooms[min_room] += e - s
return meeting_count.index(max(meeting_count))Where is the number of rooms and is the number of meetings.
Scanning all rooms for each meeting is slow. Instead, we use two min-heaps: one for available rooms (ordered by room number) and one for rooms in use (ordered by end time, then room number). When a meeting starts, we first move all rooms whose meetings have ended back to the available heap. If available is empty, we pop the earliest-ending room, delay the meeting, and push that room back to available. Then we pop the smallest available room, assign the meeting, and push it to the used heap.
available with room numbers 0 to n - 1.used storing (end_time, room).count of size n.(start, end):used is not empty and used[0].end_time <= start, pop from used and push the room to available.available is empty, pop (end_time, room) from used, update end = end_time + (end - start), and push room to available.room from available, push (end, room) to used, and increment count[room].class Solution:
def mostBooked(self, n: int, meetings: List[List[int]]) -> int:
meetings.sort()
available = [i for i in range(n)] # Min heap for available rooms
used = [] # Min heap for used rooms [(end_time, room_number)]
count = [0] * n # Count of meetings for each room
for start, end in meetings:
while used and used[0][0] <= start:
_, room = heapq.heappop(used)
heapq.heappush(available, room)
if not available:
end_time, room = heapq.heappop(used)
end = end_time + (end - start)
heapq.heappush(available, room)
room = heapq.heappop(available)
heapq.heappush(used, (end, room))
count[room] += 1
return count.index(max(count))Where is the number of rooms and is the number of meetings.
We can simplify to a single heap that tracks (end_time, room). Initially all rooms have end time 0. Before assigning a meeting, we update any rooms whose end time is before the meeting's start to have end time equal to the start (they become available). Then we pop the room with the smallest end time (and smallest room number on ties), assign the meeting, and push the room back with the new end time.
available with (0, room) for each room 0 to n - 1.count of size n.(start, end):available[0].end_time < start, pop (_, room) and push (start, room).(end_time, room) from the heap.(end_time + (end - start), room) back to the heap.count[room].class Solution:
def mostBooked(self, n: int, meetings: List[List[int]]) -> int:
meetings.sort()
available = []
count = [0] * n
for i in range(n):
heapq.heappush(available, (0, i))
for start, end in meetings:
while available and available[0][0] < start:
end_time, room = heapq.heappop(available)
heapq.heappush(available, (start, room))
end_time, room = heapq.heappop(available)
heapq.heappush(available, (end_time + (end - start), room))
count[room] += 1
return count.index(max(count))Where is the number of rooms and is the number of meetings.
Meetings must be processed in chronological order. Without sorting, you cannot correctly determine which room becomes available first or when meetings need to be delayed.
When meetings are delayed, end times can grow very large. Using int instead of long can cause overflow. Always use long or equivalent 64-bit integer types for end times.
When multiple rooms are available, you must choose the room with the smallest index. When multiple rooms become free at the same time, you must also prefer the smaller index. Failing to implement this tie-breaking correctly leads to wrong answers.
When a meeting is delayed because no room is available, the meeting duration must remain the same. The new end time should be earliest_available_time + (original_end - original_start), not simply the original end time.
When using two heaps, it is easy to forget to move rooms from the used heap back to the available heap when their meetings end. Always check and transfer rooms whose end time is at or before the current meeting's start time before attempting to assign a room.