一.直接遍历比较简单,主要是找到时间段是不是可以预定的时间,即对于集合中已有的元素(有没有元素都一样)进行遍历比较,任意拿到一个集合元素时[left, right) 与 [start, end)需要一个预定条件 ==> left >= end || start >= right 那么可知条件非为 ==> left < end && start < right, 此时产生交集,不可加入其中,返回false。
class MyCalendar {
List<int[]> booked;
public MyCalendar() {
booked = new ArrayList<int[]>();
}
public boolean book(int start, int end) {
for(int[] arr : booked){
int left = arr[0], right = arr[1];
if (left < end && start < right){
return false;
}
}
booked.add(new int[]{start, end});
return true;
}
}
/**
* Your MyCalendar object will be instantiated and called as such:
* MyCalendar obj = new MyCalendar();
* boolean param_1 = obj.book(start,end);
*/
二.二分查找,首先通过重写比较器,指定大小规则,即按照集合元素数组第一个元素大小进行比较升序。此时寻找大于或者等于end的元素[left1, right1)和前一个集合[left2, right2),那么条件为right2 <= start < end <= left1,可以预定 ==> 当找到比end大或者等于的元素时,看前一个元素的right2是否比start小,满足就可以预定,其他情况同理,代码中举了两个例子,希望可以帮助您的理解。
class MyCalendar {
TreeSet<int[]> booked;
public MyCalendar() {
// 比较器重写 按集合数组第一个元素大小进行升序
booked = new TreeSet<int[]>((o1, o2) -> o1[0] - o2[0]);
}
public boolean book(int start, int end) {
// 集合为空,直接预订
if (booked.isEmpty()){
booked.add(new int[]{start, end});
return true;
}
// 假设集合中已有[[10, 20]] ,现存储[15, 27];
// 假设集合中已有[[10, 20]], 现存储[5, 10];
// 大于等于end的第一个区间为[l1,r1),前一个区间[l2,r2);预定条件:r2 <= start < end <= l1
// 临时数组,存储当前end时间
// temp = [15, 0]
// temp = [5, 0]
int[] temp = {end, 0};
// ceiling(E e)返回此集中大于或等于(以重写的比较器比较)给定元素的最小元素,或者如果没有此类元素。null
// 获取l1
// arr = null (15 > 10 没有比给定元素大于等于的元素)
// arr = [10, 20] (5 < 10 存在比给定元素大于等于的元素)
int[] arr = booked.ceiling(temp);
// last()返回此集中当前的最后一个(最高)元素。
// lower(E e)返回此集中严格小于给定元素的最大元素,或者如果没有此类元素。null
// 获取r2 ,prev存在两种情况:集合中元素没有比end大 ==> 获取当前最大元素数组;存在比end大的元素 ==> 获取前一个元素数组
// arr 为空, prev = [10, 20];
// arr不为空, prev = null
// int[] prev = arr == null ? booked.last() : booked.lower(arr);
// first()返回此集中当前第一个(最低)元素。
// arr 与 [10, 20]不匹配 false || [10, 20]中20 > 15 false ==> false
// arr 与 [10, 20]匹配 true ==> true加入集合
if (arr == booked.first() || booked.lower(temp)[1] <= start){
booked.add(new int[]{start, end});
return true;
}
return false;
}
}
/**
* Your MyCalendar object will be instantiated and called as such:
* MyCalendar obj = new MyCalendar();
* boolean param_1 = obj.book(start,end);
*/