45. Design a Meeting Room Scheduler for Recurrent Meetings

Design a Meeting Room Scheduler for Recurrent Meetings
Design an in-memory Meeting Room Scheduler for recurrent meetings that allows employees to do the following:
  • View available rooms,
  • Book a room for meeting which repeats after a given time interval for 20 future instances,
  • Cancel a booking and all its instances, and
  • List bookings by room or by employee.

Core Rules

  • Rooms are identified by integer IDs: 0 to roomsCount - 1.
  • Employees are identified by integer IDs: 0 to employeesCount - 1.
  • A booking reserves exactly one room for exactly one employee during a time interval.
  • Time interval convention: treat a booking as [startTime, startTime+duration-1].
    • Both startTime and endTime are inclusive
    • This means: Meeting intervals [10, 20] and [20, 30] do overlap each other.
  • No double-booking: the same room cannot have overlapping bookings.

Methods

  • constructor: MeetingRoomScheduler(int roomsCount, int employeesCount)
    Initializes an in-memory scheduler with a fixed set of rooms and employees.
    • roomsCount > 0, employeesCount > 0.
    • room ids's are between 0 and roomsCount-1
    • employee id's are between 0 and employeesCount-1
  • boolean bookRoom(String bookingId, int employeeId, int roomId, int startTime, int duration, int repeatDuration)
    Attempts to create a booking for the given room and employee.
    Creates a recurring meeting which repeats after repeatDuration in the same room.
    i.e. startTime, startTime+repeatDuration, startTime+2*repeatDuration ... startTime+19*repeatDuration i.e. till 20 occurances.
    • bookingId is always unique and non-blank.
    • employeeId and roomId are always valid.
    • duration<repeatDuration, both are positive integers.
    • Invalid time range: if duration<=0, or startTime<0 then return false.
    • If the room has no overlapping booking in [startTime, startTime+duration-1], from existing recurrent meetings (check all occurances) then create the booking and return true.
    • If the room already has an overlapping booking, return false (do not partially add anything).
  • List<Integer> getAvailableRooms(int startTime, int endTime)
    Returns the list of room IDs that are free for the entire interval.
    • Invalid time range: if startTime > endTime, return an empty list.
    • Return room IDs in ascending order.
  • boolean cancelBooking(String bookingId)
    Cancels all instances an existing booking by its ID.
    • Return true if a booking with this ID existed and was removed.
    • Return false if the booking ID does not exist (no-op).
  • List<String> listBookingsForRoom(int roomId, int n)
    • Returns a list of first n bookings(or empty list).
    • Format of each row is bookingId-startTime-endTime
    • Returned list will be sorted by start time of meetings in ascending order.
  • List<String> listBookingsForEmployee(int employeeId, int n)
    Returns a list of first n bookings for that employee (or empty list).
    • Each row in the list is of the format bookingId-startTime-endTime
    • Return bookings sorted by startTime in ascending order.

Examples:

Example 1: Recurrence, overlap (same room), boundary conflict, different-room overlap, availability, cancel, listing


MeetingRoomScheduler s = new MeetingRoomScheduler(2, 2);  // rooms: 0,1  employees: 0,1

// Initially, both rooms are free.
s.getAvailableRooms(10, 12)
=> [0, 1]

// Book a recurring meeting in room 0:
// bookingId=b1, employee=0, room=0, start=10, duration=3 => [10,12]
// repeats every 5 for exactly 20 occurrences:
// occurrence starts: 10, 15, 20, ... , 10 + 19*5 = 105
// last occurrence interval: [105, 107]
s.bookRoom("b1", 0, 0, 10, 3, 5)
=> true

// Availability check: at time=12, room0 is busy due to b1's first occurrence [10,12]
s.getAvailableRooms(12, 12)
=> [1]

// Overlap in SAME room due to CLOSED interval boundary:
// b2 is [12,12] (duration=1) which overlaps b1's [10,12] at time=12
s.bookRoom("b2", 1, 0, 12, 1, 10)
=> false

// Another overlap in SAME room:
// b3 is [16,16], but b1 has an occurrence [15,17], so it overlaps
s.bookRoom("b3", 1, 0, 16, 1, 10)
=> false

// Different room can overlap in time freely:
// b4 in room 1: start=12, duration=2 => [12,13], repeats every 6 for 20 occurrences
// last occurrence starts at 12 + 19*6 = 126 => last interval [126,127]
s.bookRoom("b4", 1, 1, 12, 2, 6)
=> true

// Now, within [12,12], room0 is busy (b1) and room1 is busy (b4)
s.getAvailableRooms(12, 12)
=> []

// List first 5 occurrences for room 0 (only b1 exists there)
s.listBookingsForRoom(0, 5)
=> ["b1-10-12", "b1-15-17", "b1-20-22", "b1-25-27", "b1-30-32"]

// List first 4 occurrences for room 1 (only b4 exists there)
s.listBookingsForRoom(1, 4)
=> ["b4-12-13", "b4-18-19", "b4-24-25", "b4-30-31("")]

// Employee-wise listing (first 3 occurrences)
s.listBookingsForEmployee(0, 3)
=> ["b1-10-12", "b1-15-17", "b1-20-22"]

s.listBookingsForEmployee(1, 3)
=> ["b4-12-13", "b4-18-19", "b4-24-25("")]

// Cancel removes ALL 20 occurrences of that recurring booking
s.cancelBooking("b1")
=> true

// Now room0 is free in [10,12], but room1 is still busy at 12 due to b4
s.getAvailableRooms(10, 12)
=> [0]

// Cancelling again is a no-op
s.cancelBooking("b1")
=> false

  

Example 2: Edge cases: invalid inputs, duration vs repeatDuration constraint, instant meeting, invalid availability query


MeetingRoomScheduler s = new MeetingRoomScheduler(1, 1);  // room: 0  employee: 0

s.listBookingsForRoom(0, 5)
=> []

s.listBookingsForEmployee(0, 5)
=> []

// Invalid: startTime < 0
s.bookRoom("x1", 0, 0, -1, 1, 5)
=> false

// Invalid: duration <= 0
s.bookRoom("x2", 0, 0, 10, 0, 5)
=> false

// Invalid per rule: duration < repeatDuration is required (so duration == repeatDuration is not allowed)
s.bookRoom("x3", 0, 0, 10, 5, 5)
=> false

// Valid "instant" booking: duration=1 => interval [20,20], repeats every 7 for 20 occurrences
// occurrence times: 20, 27, 34, ... , 20 + 19*7 = 153
s.bookRoom("x4", 0, 0, 20, 1, 7)
=> true

// Invalid availability query (startTime > endTime)
s.getAvailableRooms(30, 10)
=> []

// At time=20, room0 is busy
s.getAvailableRooms(20, 20)
=> []

// With "check all 20 occurrences":
// x5 occurrence times: 21, 29, 37, 45, 53, 61, 69, ...
// x4 occurrence times: 20, 27, 34, 41, 48, 55, 62, 69, ...
// They overlap at time=69 within the first 20 occurrences, so booking must be rejected.
s.bookRoom("x5", 0, 0, 21, 1, 8)
=> false

// So only x4 appears in listings
s.listBookingsForRoom(0, 6)
=> ["x4-20-20", "x4-27-27", "x4-34-34", "x4-41-41", "x4-48-48", "x4-55-55"]

s.cancelBooking("does-not-exist")
=> false

s.cancelBooking("x4")
=> true

// Now time=20 becomes free
s.getAvailableRooms(20, 20)
=> [0]

  




Please use Laptop/Desktop or any other large screen to add/edit code.