731. My Calendar II
1. 题目描述
题目链接
Implement a MyCalendar class to store your events. A new event can be added if adding the event will not cause a double booking.
Your class will have the 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 double booking happens when two events have some non-empty intersection (ie., there is some time that is common to both events.)
For each call to the method MyCalendar.book, return 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.
Your class will be called like this: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)Example 1:
MyCalendar();
MyCalendar.book(10, 20); // returns true
MyCalendar.book(15, 25); // returns false
MyCalendar.book(20, 30); // returns true
Explanation:
The first event can be booked. The second can’t because time 15 is already booked by another event.
The third event can be booked, as the first event takes every time less than 20, but not including 20.
Note:
The number of calls to MyCalendar.book per test case will be at most 1000.
In calls to MyCalendar.book(start, end), start and end are integers in the range [0, 10^9].
2. 题目分析
根据My Calendar I 改编,My Calendar I 是判断是否两个区间重叠,而这题是否存在三个区间存在重叠。
3. 解决思路
那么我们可以用一个集合来专门存重叠区间,再用一个集合来存完整的区间,那么我们的思路就是,先遍历专门存重叠区间的集合,因为能在这里出现的区间,都已经是出现两次了,如果当前新的区间跟重叠区间有交集的话,说明此时三个区间重叠了,直接返回false。如果当前区间跟重叠区间没有交集的话,那么再来遍历完整区间的集合,如果有交集的话,那么应该算出重叠区间并且加入放重叠区间的集合中。最后将新区间加入完整区间的集合中。
分别有两个区间overList(存储两个区间的重叠区域)和bookedList(存储所有区间)
- 判断是否有与overList重叠,如果有,则说明已经存在三个重叠区域,直接返回false
- 判断新加入的区间是否与bookedList中的区间重叠,若有,则将重叠区域加入overList
- 新的区间加入bookedList
4. 代码实现(java)
package com.algorithm.leetcode.binarytree;
import java.util.LinkedList;
import java.util.List;
/**
* Created by 凌 on 2019/1/4.
* 描述:731. 我的日程安排表 II
*/
public class MyCalendarTwo {
/**
* 存储重叠区域
*/
private List<Integer[]> overList;
/**
* 存储正常event
*/
private List<Integer[]> bookedList;
public MyCalendarTwo() {
overList = new LinkedList<>();
bookedList = new LinkedList<>();
}
public boolean book(int start, int end) {
if (start >= end){
return false;
}
//在重叠区域中,找是否存在重叠,如果说,说明有三个区间存在重叠区域,返回false
for (Integer[] over : overList){
//Math.max(start,over[0]) < Math.min(end,over[1]) 等于 start >= over[1] || end <= over[0]的补集
if (Math.max(start,over[0]) < Math.min(end,over[1])){
return false;
}
}
Integer[] temp;
for (Integer[] booked : bookedList){
int newStart = Math.max(start,booked[0]);
int newEnd = Math.min(end,booked[1]);
if (newStart < newEnd){
temp = new Integer[2];
temp[0] = newStart;
temp[1] = newEnd;
overList.add(temp);
}
}
bookedList.add(new Integer[]{start,end});
return true;
}
}
/**
* Your MyCalendarTwo object will be instantiated and called as such:
* MyCalendarTwo obj = new MyCalendarTwo();
* boolean param_1 = obj.book(start,end);
*/