A k
-booking happens when k
events have some non-empty intersection (i.e., there is some time that is common to all k
events.)
You are given some events [startTime, endTime)
, after each given event, return an integer k
representing the maximum k
-booking between all the previous events.
Implement the MyCalendarThree
class:
MyCalendarThree()
Initializes the object.int book(int startTime, int endTime)
Returns an integer k
representing the largest integer such that there exists a k
-booking in the calendar.Example 1:
Input ["MyCalendarThree", "book", "book", "book", "book", "book", "book"] [[], [10, 20], [50, 60], [10, 40], [5, 15], [5, 10], [25, 55]] Output [null, 1, 1, 2, 3, 3, 3] Explanation MyCalendarThree myCalendarThree = new MyCalendarThree(); myCalendarThree.book(10, 20); // return 1 myCalendarThree.book(50, 60); // return 1 myCalendarThree.book(10, 40); // return 2 myCalendarThree.book(5, 15); // return 3 myCalendarThree.book(5, 10); // return 3 myCalendarThree.book(25, 55); // return 3
Constraints:
0 <= startTime < endTime <= 109
400
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 calendar problem wants us to find the maximum number of overlapping events. The brute force method simply checks every possible event overlap for each new event we add to the calendar. It's like trying every single possibility to see which one works.
Here's how the algorithm would work step-by-step:
class MyCalendarThree:
def __init__(self):
self.calendar_events = []
def book(self, start_time: int, end_time: int) -> int:
self.calendar_events.append((start_time, end_time))
maximum_overlapping_events = 0
# Iterate through all events to find max overlaps
for i in range(len(self.calendar_events)):
current_overlap_count = 0
event_one_start = self.calendar_events[i][0]
event_one_end = self.calendar_events[i][1]
# Compare current event with every other event
for j in range(len(self.calendar_events)):
if i == j:
current_overlap_count = max(current_overlap_count, 1)
continue
event_two_start = self.calendar_events[j][0]
event_two_end = self.calendar_events[j][1]
# Check if two events overlap
if event_one_start < event_two_end and event_two_start < event_one_end:
current_overlap_count += 1
maximum_overlapping_events = max(maximum_overlapping_events, current_overlap_count)
return maximum_overlapping_events
We want to efficiently track the maximum number of overlapping events at any given time. To do this, we focus on when events start and end, instead of checking every possible time point.
Here's how the algorithm would work step-by-step:
class MyCalendarThree:
def __init__(self):
self.timeline = {}
def book(self, start_time: int, end_time: int) -> int:
# Use +1 for start, -1 for end to track overlaps.
self.timeline[start_time] = self.timeline.get(start_time, 0) + 1
self.timeline[end_time] = self.timeline.get(end_time, 0) - 1
sorted_times = sorted(self.timeline.keys())
current_overlaps = 0
max_overlaps = 0
# Iterate through sorted times to maintain overlap count.
for time_point in sorted_times:
current_overlaps += self.timeline[time_point]
# Update max overlaps seen so far.
max_overlaps = max(max_overlaps, current_overlaps)
return max_overlaps
Case | How to Handle |
---|---|
Empty input stream of events | The data structure should initialize and allow bookings even without initial events and return 0 as the maximum overlapping events. |
Integer overflow of start or end times | Use appropriate data types (e.g., long) or modular arithmetic to prevent integer overflows when calculating overlaps. |
Large number of events exceeding available memory | Consider using a segment tree or interval tree data structure that scales better with a large number of events, possibly offloading to disk. |
Events with identical start and end times | Increment and decrement counters at the same index to correctly represent zero duration events, ensuring they don't improperly increase k. |
Events that completely overlap other existing events | Increment the counter for the start of the completely overlapping event and decrement the counter for its end, adding to the existing overlap. |
Events with very small durations or very large durations | The chosen data structure and algorithm should handle very small or very large durations without loss of precision or efficiency. |
Overlapping events with identical start times | The data structure must correctly account for overlapping events at the same start time by incrementing the active count appropriately. |
Consecutive bookings with near-identical start/end times causing floating-point precision issues if using floating-point | Use integers for start/end times, avoiding floating-point precision issues; if not possible, apply a small epsilon value when comparing times. |