732. My Calendar III
week13
难度:Hard
题目描述
Implement a MyCalendarThree class to store your events. A new event can always be added.
Your class will have one method, book(int start, int end). Formally, this represents a booking on the half open interval [start, end), the range of real numbers x such that start <= x < end.
A K-booking happens when K events have some non-empty intersection (ie., there is some time that is common to all K events.)
For each call to the method MyCalendar.book, return an integer K representing the largest integer such that there exists a K-booking in the calendar.
Your class will be called like this: MyCalendarThree cal = new MyCalendarThree(); MyCalendarThree.book(start, end)
Example1:
MyCalendarThree();
MyCalendarThree.book(10, 20); // returns 1
MyCalendarThree.book(50, 60); // returns 1
MyCalendarThree.book(10, 40); // returns 2
MyCalendarThree.book(5, 15); // returns 3
MyCalendarThree.book(5, 10); // returns 3
MyCalendarThree.book(25, 55); // returns 3
Explanation:
The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking.
The third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking.
The remaining events cause the maximum K-booking to be only a 3-booking.
Note that the last event locally causes a 2-booking, but the answer is still 3 because
eg. [10, 20), [10, 40), and [5, 15) are still triple booked.
Note:
- The number of calls to MyCalendarThree.book per test case will be at most 400.
- In calls to MyCalendarThree.book(start, end), start and end are integers in the range [0, 10^9].
题目分析
题目简单来说,就是寻找最大的重合数量,可以看作为有许多条线段在一个区间上,每加入一条线段则要得出最大的重叠数量,重叠就是指线段有一段重合的区间则这两条线段重叠。
解题思路
这道题我想的是如果要求最大重叠数量,假如对每条线段都去遍历一遍得出重合的线段再统计的话就很麻烦,即使维护一个最大数量每次插入后比较,也并不会很好做。
对于这个题目可以想到这么一种做法,记录下每一条线段的起点与终点,然后在这一个区间上遍历,如果遇到起点,那么此时有一条线段加入,如果遇到终点,即意味着有一条线段结束了,通过这种做法可以得出在某个点上线段有多少条,求出最大的即可。
在数据结构上选择map可以不用考虑排序的问题,而且键值对便于修改。加入线段,线段的起点数值+1,终点-1,这样在遍历这整个区间时,直接加上该点的数值即可方便统计线段数量。
代码
1 | class MyCalendarThree |
结果反思
![upload successful](\images\pasted-15.png)
这个算法虽然运行速度不快,但是胜于非常简单。。很容易理解。代码也非常简洁,就那么几行搞定,主要是要选择适合的数据结构存储。
总结
这个方法其实是有向图的一个变形,用到了出度和入度的方法,就和我说的初始和闭合一样,到初始点数量++,到了终点数量–。所以最大数量总是在某个线段开始的地方的,因此就转变为了寻找最大的出度。