Approach #1: Brute Force [Accepted]
Intuition
When booking a new event [start, end)
, check if every current event conflicts with the new event. If none of them do, we can book the event.
Algorithm
We will maintain a list of interval events (not necessarily sorted). Evidently, two events [s1, e1)
and [s2, e2)
do not conflict if and only if one of them starts after the other one ends: either e1 <= s2
OR e2 <= s1
. By De Morgan's laws, this means the events conflict when s1 < e2
AND s2 < e1
.
Complexity Analysis

Time Complexity: , where is the number of events booked. For each new event, we process every previous event to decide whether the new event can be booked. This leads to complexity.

Space Complexity: , the size of the
calendar
.
Approach #2: Balanced Tree [Accepted]
Intuition
If we maintained our events in sorted order, we could check whether an event could be booked in time (where is the number of events already booked) by binary searching for where the event should be placed. We would also have to insert the event in our sorted structure.
Algorithm
We need a data structure that keeps elements sorted and supports fast insertion. In Java, a TreeMap
is the perfect candidate. In Python, we can build our own binary tree structure.
For Java, we will have a TreeMap
where the keys are the start of each interval, and the values are the ends of those intervals. When inserting the interval [start, end)
, we check if there is a conflict on each side with neighboring intervals: we would like calendar.get(prev)) <= start <= end <= next
for the booking to be valid (or for prev
or next
to be null respectively.)
For Python, we will create a binary tree. Each node represents some interval [self.start, self.end)
while self.left, self.right
represents nodes that are smaller or larger than the current node.
Complexity Analysis

Time Complexity (Java): , where is the number of events booked. For each new event, we search that the event is legal in time, then insert it in time.

Time Complexity (Python): worst case, with on random data. For each new event, we insert the event into our binary tree. As this tree may not be balanced, it may take a linear number of steps to add each event.

Space Complexity: , the size of the data structures used.
Analysis written by: @awice. Solutions in Approach #2 inspired by @shawngao and @persianPanda.