博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[LeetCode] My Calendar II 我的日历之二
阅读量:6615 次
发布时间:2019-06-24

本文共 3802 字,大约阅读时间需要 12 分钟。

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.

A 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 trueMyCalendar.book(50, 60); // returns trueMyCalendar.book(10, 40); // returns trueMyCalendar.book(5, 15); // returns falseMyCalendar.book(5, 10); // returns trueMyCalendar.book(25, 55); // returns trueExplanation: 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].

这道题是的拓展,之前那道题说是不能有任何的重叠区间,而这道题说最多容忍两个重叠区域,注意是重叠区域,不是事件。比如事件A,B,C互不重叠,但是有一个事件D,和这三个事件都重叠,这样是可以的,因为重叠的区域最多只有两个。所以关键还是要知道具体的重叠区域,如果两个事件重叠,那么重叠区域就是它们的交集,求交集的方法是两个区间的起始时间中的较大值,到结束时间中的较小值。那么我们可以用一个集合来专门存重叠区间,再用一个集合来存完整的区间,那么我们的思路就是,先遍历专门存重叠区间的集合,因为能在这里出现的区间,都已经是出现两次了,如果当前新的区间跟重叠区间有交集的话,说明此时三个事件重叠了,直接返回false。如果当前区间跟重叠区间没有交集的话,那么再来遍历完整区间的集合,如果有交集的话,那么应该算出重叠区间并且加入放重叠区间的集合中。最后记得将新区间加入完整区间的集合中,参见代码如下:

解法一:

public:    MyCalendarTwo() {}        bool book(int start, int end) {        for (auto a : s2) {            if (start >= a.second || end <= a.first) continue;            else return false;        }        for (auto a : s1) {            if (start >= a.second || end <= a.first) continue;            else s2.insert({max(start, a.first), min(end, a.second)});        }        s1.insert({start, end});        return true;    }private:    set
> s1, s2;};

下面这种方法相当的巧妙,我们建立一个时间点和次数之间的映射,规定遇到起始时间点,次数加1,遇到结束时间点,次数减1。那么我们首先更改新的起始时间start和结束时间end的映射,start对应值增1,end对应值减1。然后定义一个变量cnt,来统计当前的次数。我们使用treemap具有自动排序的功能,所以我们遍历的时候就是按时间顺序的,最先遍历到的一定是一个起始时间,所以加上其映射值,一定是个正数。那么我们想,如果此时只有一个区间,就是刚加进来的区间的话,那么首先肯定遍历到start,那么cnt此时加1,然后就会遍历到end,那么此时cnt减1,最后下来cnt为0,没有重叠。还是用具体数字来说吧,我们现在假设treemap中已经加入了一个区间[3, 5)了,那么我们就有下面的映射:

3 -> 1

5 -> -1

假如我们此时要加入的区间为[6, 8)的话,那么在遍历到6的时候,前面经过3和5,分别加1减1,那么cnt又重置为0了,而后面的6和8也是分别加1减1,还是0。那么加入我们新加入的区间为[3, 8]时,那么此时的映射为:

3 -> 2

5 -> -1

8 -> -1

那么我们最先遍历到3,cnt为2,没有超过3,我们知道此时有两个事件有重叠,是允许的。然后遍历5和8,分别减去1,最终又变成0了,始终cnt没有超过2,所以是符合题意的。如果此时我们再加入一个新的区间[1, 4),那么此时的映射为:

1 -> 1

3 -> 2

4 -> -1

5 -> -1

8 -> -1

那么我们先遍历到1,cnt为1,然后遍历到3,此时cnt为3了,那么我们就知道有三个事件有重叠区间了,所以这个新区间是不能加入的,那么我们要还原其start和end做的操作,把start的映射值减1,end的映射值加1,然后返回false。否则没有三个事件有共同重叠区间的话,返回true即可,参见代码如下:

解法二:

public:    MyCalendarTwo() {}        bool book(int start, int end) {        ++freq[start];        --freq[end];        int cnt = 0;        for (auto f : freq) {            cnt += f.second;            if (cnt == 3) {                --freq[start];                ++freq[end];                return false;            }        }        return true;    }private:    map
freq;};

参考资料:

本文转自博客园的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
GNU make manual 翻译(八十二)
查看>>
python批量下载图片的三种方法
查看>>
/bin/bash^M: bad interpreter: 没有那个文件或目录
查看>>
iOS - OC NSData 数据
查看>>
Java web 开发填坑记 1 -如何正确的下载 eclipse
查看>>
iOS - Quartz 2D 第三方框架 Charts 绘制图表
查看>>
MM顾问的常见面试问题(ZZ)
查看>>
转:Windows 8上强制Visual Studio以管理员身份运行
查看>>
迟来的加勒比海盗3 观后
查看>>
类与对象 - PHP手册笔记
查看>>
谈一谈互联网创业补贴变味后的现象
查看>>
MapGIS转Shp文件的单位问题
查看>>
使用Karate轻松实现自动API测试
查看>>
React
查看>>
CentOS -bash: warning: setlocale: LC_MESSAGES: cannot change locale (en_US.UTF-8)
查看>>
编写一个基本的Android应用程序
查看>>
我的友情链接
查看>>
查看Linux操作系统安装的位数(getconf 命令应用)
查看>>
前后端中转服务remoteService的设计与实现
查看>>
ifstream读取文件失败和乱码问题
查看>>