LeetCode Β· #2402

Meeting Rooms III Solution

You have n rooms numbered 0 to n-1. Schedule meetings in the lowest-numbered available room; if all busy, wait for the earliest to free up. Return the room with the most meetings.

01
Section One Β· Problem

Problem Statement

🏷️

Difficulty

Hard

πŸ”—

LeetCode

Problem #2402

πŸ—οΈ

Pattern

Intervals β€” two heaps (available + busy)

Given n rooms and sorted meetings[i] = [start, end], assign each meeting to the lowest-numbered available room. If all rooms are busy, delay the meeting until the earliest room frees. Return the room that held the most meetings (ties: lowest number).

Example
Input: n = 2, meetings = [[0,10],[1,5],[2,7],[3,4]] Output: 0 // Room 0: meeting[0] at [0,10], then meeting[2] delayed to [10,15]. 2 meetings. // Room 1: meeting[1] at [1,5], then meeting[3] at [5,6]. 2 meetings. // Tie β†’ room 0 (lowest number).
Constraints
β€’ 1 ≀ n ≀ 100 β€’ 1 ≀ meetings.length ≀ 10⁡ β€’ 0 ≀ startα΅’ < endα΅’ ≀ 5 Γ— 10⁡
02
Section Two Β· Approach 1

Brute Force β€” O(mΒ·n)

For each meeting, scan all n rooms to find the available one with the lowest number or the one that frees earliest.

Problem: O(mΒ·n) where m=meetings, n=rooms. Use two heaps: available rooms (min-heap by room#) and busy rooms (min-heap by free time, then room#). O(m log n).
Java β€” O(mΒ·n) simulation
import java.util.*; class Solution { public int mostBooked(int n, int[][] meetings) { Arrays.sort(meetings, (a,b) -> a[0] - b[0]); long[] endTime = new long[n]; int[] count = new int[n]; for (int[] m : meetings) { int best = -1; long earliest = Long.MAX_VALUE; for (int r = 0; r < n; r++) { if (endTime[r] <= m[0]) { best = r; break; } if (endTime[r] < earliest) { earliest = endTime[r]; best = r; } } long start = Math.max(endTime[best], m[0]); endTime[best] = start + (m[1] - m[0]); count[best]++; } int ans = 0; for (int r = 1; r < n; r++) if (count[r] > count[ans]) ans = r; return ans; } }
Python β€” O(mΒ·n) simulation
class Solution: def mostBooked(self, n: int, meetings: list[list[int]]) -> int: meetings.sort() end_time = [0] * n count = [0] * n for s, e in meetings: best = min(range(n), key=lambda r: (max(end_time[r], s), r) if end_time[r] <= s else (end_time[r], r)) # Find earliest available or earliest freeing avail = [r for r in range(n) if end_time[r] <= s] if avail: best = min(avail) else: best = min(range(n), key=lambda r: (end_time[r], r)) start = max(end_time[best], s) end_time[best] = start + (e - s) count[best] += 1 return count.index(max(count))
03
Section Three Β· Approach 2

Two Heaps β€” O(m log n)

Maintain two min-heaps: available (free room numbers) and busy (pairs of [freeTime, roomNumber]). For each meeting, move rooms that have freed up from busy β†’ available. Assign to lowest available room, or wait for earliest-freeing busy room.

πŸ’‘ Mental model: Two queues at a hotel front desk. The "available" queue holds room keys sorted by number. The "busy" queue holds rooms sorted by when they'll be free. For each guest: check if any rooms freed up (transfer keys to available). If available, assign the lowest key. If not, wait for the earliest checkout, assign that room (with delay). Count bookings per room.
Algorithm
  • Sort meetings by start time.
  • available = min-heap of [0, 1, ..., n-1]. busy = min-heap of (endTime, roomId).
  • For each meeting [s, e]:
  • While busy.peek().endTime ≀ s: move room to available.
  • If available not empty: assign room = available.poll(). Push (e, room) to busy.
  • Else: (freeTime, room) = busy.poll(). Push (freeTime + (e-s), room) to busy (delayed).
  • count[room]++.
  • Return room with max count (ties: lowest number).
🎯 When to recognize this pattern: "Assign resources by priority with delays." Two heaps (available + busy) is the standard approach for resource scheduling with queuing. Also appears in task scheduler problems and OS scheduling simulations.
04
Section Four Β· Trace

Visual Walkthrough

Trace for n=2, meetings=[[0,10],[1,5],[2,7],[3,4]].

Meeting Rooms III β€” Two Heaps
available=[0,1]. busy=[]. Process sorted meetings. [0,10]: avail has room 0 β†’ assign. busy=[(10,0)]. avail=[1]. count[0]=1. [1,5]: no rooms freed (10>1). avail has room 1 β†’ assign. busy=[(5,1),(10,0)]. count[1]=1. [2,7]: no rooms freed (5>2). avail empty β†’ wait. Earliest: (5,1). Delay: room 1 at [5,10]. count[1]=2. [3,4]: no rooms free. Earliest: (10,0). Delay: room 0 at [10,11]. count[0]=2. count=[2,2]. Tie β†’ room 0 βœ“
05
Section Five Β· Implementation

Code β€” Java & Python

Java β€” Two heaps
import java.util.*; class Solution { public int mostBooked(int n, int[][] meetings) { Arrays.sort(meetings, (a,b) -> a[0] - b[0]); PriorityQueue<Integer> avail = new PriorityQueue<>(); // busy: [endTime, roomId] PriorityQueue<long[]> busy = new PriorityQueue<>( (a,b) -> a[0] != b[0] ? Long.compare(a[0],b[0]) : Long.compare(a[1],b[1])); for (int i = 0; i < n; i++) avail.offer(i); int[] count = new int[n]; for (int[] m : meetings) { long start = m[0], dur = m[1] - m[0]; // Free up rooms that ended by now while (!busy.isEmpty() && busy.peek()[0] <= start) avail.offer((int) busy.poll()[1]); if (!avail.isEmpty()) { int room = avail.poll(); busy.offer(new long[]{m[1], room}); count[room]++; } else { long[] earliest = busy.poll(); int room = (int) earliest[1]; busy.offer(new long[]{earliest[0] + dur, room}); count[room]++; } } int ans = 0; for (int i = 1; i < n; i++) if (count[i] > count[ans]) ans = i; return ans; } }
Python β€” Two heaps
import heapq class Solution: def mostBooked(self, n: int, meetings: list[list[int]]) -> int: meetings.sort() avail = list(range(n)) # min-heap of room ids busy: list[tuple] = [] # (endTime, roomId) count = [0] * n for s, e in meetings: while busy and busy[0][0] <= s: _, room = heapq.heappop(busy) heapq.heappush(avail, room) if avail: room = heapq.heappop(avail) heapq.heappush(busy, (e, room)) else: free_time, room = heapq.heappop(busy) heapq.heappush(busy, (free_time + e - s, room)) count[room] += 1 return count.index(max(count))
06
Section Six Β· Analysis

Complexity Analysis

ApproachTimeSpaceTrade-off
Brute simulationO(mΒ·n)O(n)Linear scan per meeting
Two heaps ← optimalO(m log n)O(n)Heap operations for available + busy rooms
07
Section Seven Β· Edge Cases

Edge Cases & Pitfalls

CaseInputWhy It Matters
More rooms than meetingsn=5, m=2Each meeting gets its own room. Most booked: lowest with 1 meeting.
One roomn=1All meetings sequentially delayed. Room 0 has all meetings.
All concurrentn=2, [[0,5],[0,5],[0,5]]Room 0: [0,5], room 1: [0,5], third waits for room 0 β†’ [5,10].
Delayed chainn=1, [[0,10],[1,2],[3,4]]All delayed: [0,10],[10,11],[11,12]. Room 0: 3 meetings.
OverflowLarge start/end valuesUse long for endTime to avoid integer overflow when delays accumulate.
⚠ Common Mistake: Using int for end times. When meetings are delayed, end times accumulate: a meeting originally [0, 500000] delayed 100000 times would overflow. Always use long (Java) or Python's arbitrary-precision ints. Also: when all rooms are busy, the delay duration is e - s (original duration), not e β€” don't forget to add the delay to the freed room's end time.

← Back to Interval problems