Hotel/Room/RoomType/Reservation classes, efficient date-range availability search via interval representation, and overbooking as a deliberate business rule rather than a bug.
Published September 23, 2026
class Hotel { List<Room> rooms; }
class RoomType { String name; double basePrice; int capacity; } // Standard, Deluxe, Suite
class Room { String number; RoomType type; }
class Reservation { Room room; Guest guest; LocalDate checkIn; LocalDate checkOut; }
The naive approach — for each candidate room, scan every existing reservation checking for date overlap — is O(rooms * reservations per room) per search, which gets slow as reservation history grows. The better representation: for each room, keep reservations in a structure that supports fast interval overlap queries.
class Room {
private final TreeMap<LocalDate, Reservation> reservationsByCheckIn = new TreeMap<>(); // sorted by check-in date
boolean isAvailable(LocalDate checkIn, LocalDate checkOut) {
// Find the reservation with the latest check-in date that's still <= requested checkOut
Map.Entry<LocalDate, Reservation> candidate = reservationsByCheckIn.floorEntry(checkOut.minusDays(1));
if (candidate == null) return true; // no reservation starts before the requested window ends
Reservation r = candidate.getValue();
return !r.getCheckOut().isAfter(checkIn); // the closest-preceding reservation must fully end before our check-in
}
}
A TreeMap sorted by check-in date turns "is there any overlapping reservation" into a single floorEntry() lookup (O(log n)) that finds the most relevant candidate directly, rather than scanning every reservation for this room. This is the same underlying idea as TreeMap & LinkedHashMap's NavigableMap range-query methods, applied to interval scheduling specifically.
Real hotels (and airlines — see Airline Booking / Seat Selection System) deliberately overbook by a small, statistically-modeled margin, betting that historical no-show rates will absorb the overage. This is worth naming explicitly in a design discussion: a strict "never allow more reservations than physical rooms" constraint is the simpler design, but a real hotel booking system needs an explicit overbooking policy as a configurable business parameter (e.g. "allow up to 5% overbooking on RoomType") — and critically, needs a defined contingency process for the rare case where overbooking doesn't get absorbed by no-shows (walking a guest to a partner hotel, compensation). Treating overbooking as an unambiguous bug to eliminate, rather than asking whether it's an intentional business lever, is a common miss in this exact prompt.
Q: How would you extend isAvailable() to search across an entire RoomType rather than one specific room? A: Iterate the RoomType's rooms checking isAvailable() on each, returning the first (or all) available ones — the per-room interval check is the same, this just adds an outer loop; for a hotel with many rooms per type, this could be further optimized by only checking a subset if the caller just needs 'at least one available' rather than a full list.
Q: What's a concrete failure mode of the naive full-scan availability check at scale? A: A large hotel chain with years of reservation history and thousands of rooms would make every search request scan thousands of reservation records per room checked — the TreeMap approach keeps each individual room's lookup to O(log n) regardless of how much reservation history has accumulated.
Q: How would overbooking policy interact with the reservation confirmation flow from Movie Ticket Booking System's temporary-hold pattern? A: The same hold-with-expiry pattern applies directly — a room search result being 'available' doesn't guarantee it stays available through checkout, so a temporary hold during the booking flow prevents two guests from both confirming the same (already-overbooked-to-its-limit) room type simultaneously, exactly the same race the seat-booking hold pattern prevents.
Q: Should room pricing be a field on Room, or computed dynamically? A: Modeling it as dynamically computed (a PricingStrategy, matching the Strategy pattern used throughout this course) is generally the better design — real hotel pricing varies by date, demand, and length of stay, which a static price field on Room can't express, while a pluggable pricing strategy keeps that variability isolated from the room/reservation data model itself.