You are implementing a program to use as your calendar. We can add a new event if adding the event will not cause a double booking.
A double booking happens when two events have some non-empty intersection (i.e., some moment is common to both events.).
The event can be represented as a pair of integers startTime
and endTime
that represents a booking on the half-open interval [startTime, endTime)
, the range of real numbers x
such that startTime <= x < endTime
.
Implement the MyCalendar
class:
MyCalendar()
Initializes the calendar object.boolean book(int startTime, int endTime)
Returns true
if the event can be added to the calendar successfully without causing a double booking. Otherwise, return false
and do not add the event to the calendar.Example 1:
Input ["MyCalendar", "book", "book", "book"] [[], [10, 20], [15, 25], [20, 30]] Output [null, true, false, true] Explanation MyCalendar myCalendar = new MyCalendar(); myCalendar.book(10, 20); // return True myCalendar.book(15, 25); // return False, It can not be booked because time 15 is already booked by another event. myCalendar.book(20, 30); // return True, The event can be booked, as the first event takes every time less than 20, but not including 20.
Constraints:
0 <= start < end <= 109
1000
calls will be made to book
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach for the calendar problem involves checking every possible arrangement. We consider each new event and see if it conflicts with any of the events we've already added to the calendar. If there is no conflict, we add it; otherwise, we reject it.
Here's how the algorithm would work step-by-step:
class MyCalendar:
def __init__(self):
self.calendar = []
def book(self, start_time, end_time) -> bool:
# Check if the new event overlaps with any existing events
for existing_start_time, existing_end_time in self.calendar:
if start_time < existing_end_time and end_time > existing_start_time:
# If overlap found, the event can't be booked
return False
# No overlap found, book the event
self.calendar.append((start_time, end_time))
# Always maintain sorted calendar for optimization
self.calendar.sort()
return True
# Your MyCalendar object will be instantiated and called as such:
# myCalendar = MyCalendar()
# param_1 = myCalendar.book(start,end)
The optimal strategy to solve the My Calendar I problem is to keep your existing bookings sorted. Then, when a new booking comes in, you only need to check if it overlaps with any of the existing ones. If it doesn't, you can add it to the sorted list of bookings.
Here's how the algorithm would work step-by-step:
class MyCalendar:
def __init__(self):
self.bookings = []
def book(self, start_time, end_time):
# Iterate through existing bookings to check for overlaps.
for existing_start_time, existing_end_time in self.bookings:
if start_time < existing_end_time and end_time > existing_start_time:
return False
# If no overlap is found, insert the new booking into the sorted list.
self.bookings.append((start_time, end_time))
self.bookings.sort()
return True
Case | How to Handle |
---|---|
First event to be added to the calendar (empty calendar). | The algorithm should add it directly as there are no existing events to conflict with. |
New event completely overlaps an existing event. | The solution must correctly identify this overlap and return false. |
New event is completely contained within an existing event. | The solution must correctly identify this overlap and return false. |
New event starts at the exact end time of an existing event (adjacent). | This should be considered a valid booking as there's no overlap. |
New event ends at the exact start time of an existing event (adjacent). | This should be considered a valid booking as there's no overlap. |
Extremely large start and end values (close to integer limits). | Ensure integer overflow is avoided when calculating overlaps. |
Adding a large number of events, testing scalability. | The chosen data structure (e.g., sorted list or binary search tree) should provide efficient lookup to maintain reasonable booking time complexity. |
Multiple existing events that are very close together or overlapping on boundaries. | The algorithm should iterate through all relevant existing events to determine if the new event conflicts with any. |