问题背景
实现一个程序来存放你的日程安排。如果要添加的时间内不会导致三重预订时,则可以存储这个新的日程安排。
当三个日程安排有一些时间上的交叉时(例如三个日程安排都在同一时间内),就会产生 三重预订 。
事件能够用一对整数 s t a r t T i m e startTime startTime 和 e n d T i m e endTime endTime 表示,在一个半开区间的时间 [ s t a r t T i m e , e n d T i m e ) [startTime, endTime) [startTime,endTime) 上预定。实数 x x x 的范围为 s t a r t T i m e ≤ x < e n d T i m e startTime \le x \lt endTime startTime≤x<endTime。
实现 MyCalendarTwo
类:
MyCalendarTwo()
初始化日历对象。boolean book(int startTime, int endTime)
如果可以将日程安排成功添加到日历中而不会导致三重预订,返回 t r u e true true。否则,返回 f a l s e false false 并且不要将该日程安排添加到日历中。
数据约束
● 0 ≤ s t a r t < e n d ≤ 1 0 9 0 \le start \lt end \le 10 ^ 9 0≤start<end≤109
● 每个测试用例,调用 book
方法的次数最多不超过 1000 1000 1000 次
解题过程
在需要统计重叠次数的情况下,昨天 遍历整个哈希表的做法 就不好使了。
可以额外定义一个记录重叠范围的数组,在每次加入新范围时更新,这样下一次与重叠数组的交集部分就会发生题中描述的三重预定的情况。
具体实现
class MyCalendarTwo {List<int[]> ranges;List<int[]> overlaps;public MyCalendarTwo() {ranges = new ArrayList<>();overlaps = new ArrayList<>();}public boolean book(int startTime, int endTime) {for(int[] overlap : overlaps) {if(overlap[0] < endTime && startTime < overlap[1]) {return false;}}for(int[] range : ranges) {if(range[0] < endTime && startTime < range[1]) {overlaps.add(new int[]{Math.max(range[0], startTime), Math.min(range[1], endTime)});}}ranges.add(new int[]{startTime, endTime});return true;}
}/*** Your MyCalendarTwo object will be instantiated and called as such:* MyCalendarTwo obj = new MyCalendarTwo();* boolean param_1 = obj.book(startTime,endTime);*/