My Calendar

2 篇文章 0 订阅
1 篇文章 0 订阅

leetcode problem:My Calendar1

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.

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

我们可以想象成这是一个“踢屁股”的问题,假设现在在坐标轴上有两个人(假设这A踢不到B的屁股),

然后你需要在这个坐标轴加入一个新的人,这里假设这个人加入在中间

 

我们现在就需要判断:C是否能踢到B的屁股 ;A是否能踢到C的屁股

明显可以看出,如果都踢不到,那就是证明C可以成功插入。

我们可以用 map[start] = end来表示,start表示人的位置,end表示腿长

 

class MyCalendar {
public:
    map<int,int> books;
    MyCalendar() {
        
    }
    
    bool book(int start, int end) {
         auto it = books.lower_bound(start);
        if(it!=books.end()&&end>it->first)return false; //C踢到B的屁股
        if(it!=books.begin()&&(--it)->second > start)return false; //A踢到C的屁股
        
        books[start]=end;
        return true;
    }
};

leetcode problem:My Calendar2

Implement a MyCalendarTwo class to store your events. A new event can be added if adding the event will not cause a triple booking.

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.

triple booking happens when three events have some non-empty intersection (ie., there is some time that is common to all 3 events.)

For each call to the method MyCalendar.book, return true if the event can be added to the calendar successfully without causing a triple 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(50, 60); // returns true
MyCalendar.book(10, 40); // returns true
MyCalendar.book(5, 15); // returns false
MyCalendar.book(5, 10); // returns true
MyCalendar.book(25, 55); // returns true
Explanation: 
The first two events can be booked.  The third event can be double booked.
The fourth event (5, 15) can't be booked, because it would result in a triple booking.
The fifth event (5, 10) can be booked, as it does not use time 10 which is already double booked.
The sixth event (25, 55) can be booked, as the time in [25, 40) will be double booked with the third event;
the time [40, 50) will be single booked, and the time [50, 55) will be double booked with the second event.

 

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

思路:

这题可以在My Calendar1的基础上改进,在My Calendar1上,我们不能让日期有交集(即不能踢到屁股),而在My Calendar2上,允许存在交集,但交集只允许是两个集合之间的,不能是多于两个集合之间的交集。

那么,我们可以专门把两个集合的交集记录下来,放在doubleBooking里面,在下次插入时间段到booking前,判断一下这个时间段是否与doubleBooking是否出现交集,即转化为在doubleBooking判断是否存在“踢屁股”。

如果没有出现“踢屁股”,那么我们就可以把当前这个时间段插入booking里面;

如果当前时间段与booking存在交集,则把这个交集插入doubleBooking里面。

class MyCalendarTwo {
public:
    map<int,int> doubooks;
    map<int,int> books;
    
    bool book(int start, int end) {
        auto next = doubooks.lower_bound(start);
        if(next!=doubooks.end() && next->first<end)return false;
        if(next!=doubooks.begin() && (--next)->second > start)return false;
        for(auto p:books){
            if(max(start,p.first) < min(end,p.second))
                doubooks[max(start,p.first)] = min(end,p.second);
        }
        if(!books[start])books[start]=end;//需要判断代插入的时间段的start是否已经存在,如果存在的话,只需要把交集插入到doublebooking里面就行
        return true;
    }
};

注意:插入到booking前需要判断代插入的时间段的start是否已经存在,如果存在的话,会把之前的时间段覆盖掉哦。 

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.

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)

Example 1:

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

 思路:

我们可以用“推车子装货”的思想去求出最大K

我们可以把start 标记为1(装货) ;把end标记为 -1(卸货)

我们可以从左到右进行遍历,把数值一个一个加起来,记录最大值(装进货物最多的时候)。这个最大值就是我们的K。

 

class MyCalendarThree {
public:
    map<int ,int> timeline;
    MyCalendarThree() {
        
    }
    
    int book(int start, int end) {
        timeline[start]++;
        timeline[end]--;
        
        int maxK=0,ongoing=0;
        for(pair<int,int> t:timeline){
            maxK = max(maxK,ongoing+=t.second);
        }
        return maxK;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值