729. My Calendar I

问题:

求构造类Calendar,能够记录用户录入自己的日程,日程起止时间不能重合,重合则返回false。

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].

  

解法1:

线段树?法

代码参考:

 1 class MyCalendar {
 2 private:    
 3     struct EventNode{
 4         int start;
 5         int end;
 6         struct EventNode *Left;
 7         struct EventNode *Right;
 8         EventNode(int s, int e) : start(s), end(e), Left(NULL), Right(NULL) {}
 9     };
10     
11     EventNode* head;
12 public:
13 
14     MyCalendar() {
15         head=NULL;
16     }
17     
18     bool book(int start, int end) {
19         EventNode* p=head, *prev=NULL;
20         if(!head){
21             head = new EventNode(start, end);
22             return true;
23         }
24         while(p){
25             prev=p;
26             if(start>=p->end){
27                 p=p->Right;
28             }else if(end<=p->start){
29                 p=p->Left;
30             }else if(start<p->end && end>p->start) {//★
31                 return false;
32             }
33         }
34         EventNode* newp = new EventNode(start, end);
35         if(start>=prev->end){
36             prev->Right=newp;
37         }else if(end<=prev->start){
38             prev->Left=newp;
39         }
40         
41         return true;
42     }
43 };
44 
45 /**
46  * Your MyCalendar object will be instantiated and called as such:
47  * MyCalendar* obj = new MyCalendar();
48  * bool param_1 = obj->book(start,end);
49  */

解法2:

二分查找,map法。

lower_bound为C++中二分查找,找到第一个>=参数的位置函数。

那么找到的next的key一定是>=start的。(前一位start < 新start <= next的start)

如果存在这样的next(即next!=calendar.end()),如果他的start<要判定的end,那么有 新start <= next->start < 新end,那么存在重合,返回false

如果存在next的前一位(即next!=calendar.begin()),如果 前一位的end>要判定的start,那么有 前一位start < 新start < 前一位end,那么存在重合,返回false

否则不存在重合,新加入  calendar[start]=end; 返回true

代码参考:

 1 class MyCalendar {
 2 public:
 3     map<int, int> calendar;
 4     MyCalendar() {
 5     }
 6     
 7     bool book(int start, int end) {
 8         auto next = calendar.lower_bound(start);
 9         //在有序数列calendar中二分查找,找到第一个>=start的位置。
10         if(next!=calendar.end() && next->first < end) return false;
11         if(next!=calendar.begin() && (--next)->second > start) return false;
12         calendar[start]=end;
13         return true;
14     }
15 };
16 
17 /**
18  * Your MyCalendar object will be instantiated and called as such:
19  * MyCalendar* obj = new MyCalendar();
20  * bool param_1 = obj->book(start,end);
21  */
原文地址:https://www.cnblogs.com/habibah-chang/p/12830812.html