Meeting Rooms III
The drill: n meeting rooms, numbered from zero. Each meeting claims the lowest-numbered free room, or waits for the soonest room to free and keeps its original length. Report the room with the most bookings — lowest index breaks a tie.
A fixed count of meeting rooms, numbered starting at zero, has to host a list of meetings, each with its own start and end time. Meetings are handled strictly in the order their start times fall, and every meeting always happens eventually — it's only a question of which room, and sometimes when.
If a room stands empty when a meeting is ready to begin, the meeting takes the lowest-numbered such room and runs for its intended length. If every room is busy instead, the meeting waits for whichever room frees up soonest, then runs there for its original duration starting from that later moment — its length never shrinks or grows because of the delay.
Once every meeting has been placed, the drill asks for the room that ended up hosting the most meetings overall. Ties go to whichever qualifying room has the smaller number.
- room count and number of meetings each stay in the small-to-moderate thousands
- start and end times are non-negative integers, with end always after start
- a delayed meeting keeps its original duration, just shifted later
- ties for most-bookings resolve to the lowest room index
HINT 1 THE NUDGE
Meetings must be handled start-time first. At every step you need two things ready fast: which rooms are free right now, and — if none are — which room frees up soonest.
HINT 2 THE STRUCTURE
Two min-heaps do the job: one holding free room numbers (lowest always on top), one holding (end time, room) pairs for busy rooms (soonest end always on top). Before assigning a meeting, drain every busy room whose end time has already passed into the free heap.
HINT 3 ONE STEP FROM THE ANSWER
If the free heap has a room, take it and push (this meeting's end, room) onto the busy heap. Otherwise pop the soonest-ending busy room, and re-push it with end = that free time plus this meeting's original duration, on the SAME room. Tally bookings per room and report the max, ties to the lowest index.
2 rooms, meetings sorted by start: [0,10],[1,5],[2,7],[3,4]. Lowest free room goes first; a full house waits for the soonest release.
class Solution:
def mostBooked(self, n: int, meetings: List[List[int]]) -> int:
ordered = sorted(meetings)
free = list(range(n)) # min-heap of free room numbers
busy = [] # min-heap of (end_time, room)
counts = [0] * n
i = 0
for start, end in ordered:
while busy and busy[0][0] <= start:
_, r = heapq.heappop(busy)
heapq.heappush(free, r)
if free:
r = heapq.heappop(free)
heapq.heappush(busy, (end, r))
counts[r] += 1
else:
free_time, r = heapq.heappop(busy)
heapq.heappush(busy, (free_time + (end - start), r))
counts[r] += 1
best = 0
for r in range(1, n):
if counts[r] > counts[best]:
best = r
return bestclass Solution:
def mostBooked(self, n: int, meetings: List[List[int]]) -> int:
ordered = sorted(meetings)
free_at = [0] * n
counts = [0] * n
for start, end in ordered:
duration = end - start
candidate = -1
for r in range(n):
if free_at[r] <= start:
candidate = r
break
if candidate != -1:
free_at[candidate] = end
counts[candidate] += 1
else:
best = 0
for r in range(1, n):
if free_at[r] < free_at[best]:
best = r
free_at[best] += duration
counts[best] += 1
best_room = 0
for r in range(1, n):
if counts[r] > counts[best_room]:
best_room = r
return best_roomclass Solution {
public int mostBooked(int n, int[][] meetings) {
int[][] ordered = meetings.clone();
Arrays.sort(ordered, (a, b) -> Integer.compare(a[0], b[0]));
PriorityQueue<Integer> free = new PriorityQueue<>();
for (int i = 0; i < n; i++) free.add(i);
// busy holds {endTime, room}, soonest end (then lowest room) on top
PriorityQueue<long[]> busy = new PriorityQueue<>((a, b) ->
a[0] != b[0] ? Long.compare(a[0], b[0]) : Long.compare(a[1], b[1]));
int[] counts = new int[n];
for (int[] m : ordered) {
long start = m[0], end = m[1];
while (!busy.isEmpty() && busy.peek()[0] <= start) {
long[] top = busy.poll();
free.add((int) top[1]);
}
if (!free.isEmpty()) {
int r = free.poll();
busy.add(new long[] { end, r });
counts[r]++;
} else {
long[] top = busy.poll();
int r = (int) top[1];
long newEnd = top[0] + (end - start);
busy.add(new long[] { newEnd, r });
counts[r]++;
}
}
int best = 0;
for (int r = 1; r < n; r++) {
if (counts[r] > counts[best]) best = r;
}
return best;
}
}class Solution {
public int mostBooked(int n, int[][] meetings) {
int[][] ordered = meetings.clone();
Arrays.sort(ordered, (a, b) -> Integer.compare(a[0], b[0]));
long[] freeAt = new long[n];
int[] counts = new int[n];
for (int[] m : ordered) {
long start = m[0], end = m[1];
long duration = end - start;
int candidate = -1;
for (int r = 0; r < n; r++) {
if (freeAt[r] <= start) {
candidate = r;
break;
}
}
if (candidate != -1) {
freeAt[candidate] = end;
counts[candidate]++;
} else {
int best = 0;
for (int r = 1; r < n; r++) {
if (freeAt[r] < freeAt[best]) best = r;
}
freeAt[best] += duration;
counts[best]++;
}
}
int bestRoom = 0;
for (int r = 1; r < n; r++) {
if (counts[r] > counts[bestRoom]) bestRoom = r;
}
return bestRoom;
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED