My Calendar I
Problem statement
Design a class MyCalendar that accepts bookings only when they do not clash with an existing one.
MyCalendar()creates an empty calendar.book(start, end)tries to add an event covering the half-open range[start, end): it includesstartbut notend. If the event overlaps any event already in the calendar, returnfalseand do not add it. Otherwise add it and returntrue.
Because ranges are half-open, an event ending at 20 and another starting at 20 do not overlap.
Examples
Example 1
Input: book(10, 20)
book(15, 25)
book(20, 30)
Output: true
false
true
Explanation: [15, 25) overlaps [10, 20). [20, 30) starts exactly where [10, 20) ends, which is allowed.
Example 2
Input: book(5, 10)
book(1, 6)
book(1, 5)
Output: true
false
true
Explanation: [1, 6) overlaps [5, 10) on 5. [1, 5) stops just before it.
Hints
Approach
Keep bookings ordered by start time and only check the two neighbours.
- Find where
startwould go among the sorted start times. - The booking just before that position must end at or before
start(prev_end <= start). - The booking just after it must start at or after
end(next_start >= end). - If both hold, insert the booking at that position and return
true; otherwise returnfalse.
Accepted bookings never overlap, so if the two neighbours are clear, nothing further away can clash. In Java, a TreeMap from start to end gives floorKey/ceilingKey and insertion in O(log n). Python has no built-in balanced tree, so the Python version uses bisect on sorted lists: the search is O(log n), but list.insert shifts elements and is O(n) in the worst case.
O(log n) per book (TreeMap)Space O(n)from bisect import bisect_right class MyCalendar: def __init__(self): self.starts = [] # sorted start times self.ends = [] # ends, parallel to starts def book(self, start: int, end: int) -> bool: i = bisect_right(self.starts, start) if i > 0 and self.ends[i - 1] > start: # clashes with the previous booking return False if i < len(self.starts) and self.starts[i] < end: # clashes with the next booking return False self.starts.insert(i, start) self.ends.insert(i, end) return TrueFollow-up questions
- Allow each time to be double-booked but never triple-booked.
- Return the maximum number of events overlapping at any moment after each booking.
Frequently asked questions
It is a reservation system for any exclusive resource: a shared staging environment, a lab device, a deploy lock, or a change window. "Reject the request if it clashes, otherwise record it" is the core of all of them.
With [start, end), back-to-back bookings like 10-20 and 20-30 are allowed, which matches how calendars work. The overlap test uses strict < on both sides for that reason. With closed ranges you would use <=.
The lookup is O(log n), but inserting into the middle of a list is O(n) because elements shift. It is fast in practice for thousands of bookings. For a true O(log n) insert in Python, use a balanced tree or the third-party sortedcontainers.SortedList.