[LeetCode] My Calendar I 我的日历之一
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 most1000
. - In calls to
MyCalendar.book(start, end)
,start
andend
are integers in the range[0, 10^9]
.
这道题让我们设计一个我的日历类,里面有一个book函数,需要给定一个起始时间和结束时间,与Google Calendar不同的是,我们的事件事件上不能重叠,实际上这道题的本质就是检查区间是否重叠。那么我们可以暴力搜索,对于每一个将要加入的区间,我们都和已经已经存在的区间进行比较,看是否有重复。而新加入的区间和当前区间产生重复的情况有两种,一种是新加入区间的前半段重复,并且,另一种是新加入区间的后半段重复。比如当前区间如果是[3, 8),那么第一种情况下新加入区间就是[6, 9),那么触发条件就是当前区间的起始时间小于等于新加入区间的起始时间,并且结束时间大于新加入区间的结束时间。第二种情况下新加入区间就是[2,5),那么触发条件就是当前区间的起始时间大于等于新加入区间的起始时间,并且起始时间小于新加入区间的结束时间。这两种情况均返回false,否则就将新区间加入数组,并返回true即可,参见代码如下:
解法一:
class MyCalendar {
public:
MyCalendar() {} bool book(int start, int end) {
for (auto a : cal) {
if (a.first <= start && a.second > start) return false;
if (a.first >= start && a.first < end) return false;
}
cal.push_back({start, end});
return true;
} private:
vector<pair<int, int>> cal;
};
下面这种方法将上面方法的两个if判断融合成为了一个,我们来观察两个区间的起始和结束位置的关系发现,如果两个区间的起始时间中的较大值小于结束区间的较小值,那么就有重合,返回false。比如 [3, 8) 和 [6, 9),3和6中的较大值6,小于8和9中的较小值8,有重叠。再比如[3, 8) 和 [2, 5),3和2中的较大值3,就小于8和5中的较小值5,有重叠。而对于[3, 8) 和 [9, 10),3和9中的较大值9,不小于8和10中的较小值8,所以没有重叠,参见代码如下:
解法二:
class MyCalendar {
public:
MyCalendar() {} bool book(int start, int end) {
for (auto a : cal) {
if (max(a.first, start) < min(a.second, end)) return false;
}
cal.push_back({start, end});
return true;
} private:
vector<pair<int, int>> cal;
};
上面两种解法都是线性搜索,我们起始可以优化搜索时间,如果我们的区间是有序的话。所以我们用一个map来建立起始时间和结束时间的映射,map会按照起始时间进行自动排序。然后对于新进来的区间,我们在已有区间中查找第一个不小于新入区间的起始时间的区间,如果这个区间存在的话,说明新入区间的起始时间小于等于当前区间,也就是解法一中的第二个if情况,当前区间起始时间小于新入区间结束时间的话返回false。我们还要跟前面一个区间进行查重叠操作,那么判断如果当前区间不是第一个区间的话,就找到前一个区间,此时是解法一中第一个if情况,并且如果前一个区间的结束时间大于新入区间的起始时间的话,返回false。否则就建立新的映射,返回true即可,参见代码如下:
解法三:
class MyCalendar {
public:
MyCalendar() {} bool book(int start, int end) {
auto it = cal.lower_bound(start);
if (it != cal.end() && it->first < end) return false;
if (it != cal.begin() && prev(it)->second > start) return false;
cal[start] = end;
return true;
} private:
map<int, int> cal;
};
参考资料:
https://discuss.leetcode.com/topic/111205/java-8-liner-treemap
https://discuss.leetcode.com/topic/111244/simple-c-o-n-solution
https://discuss.leetcode.com/topic/111306/clean-c-o-logn-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] My Calendar I 我的日历之一的更多相关文章
- [LeetCode] My Calendar III 我的日历之三
Implement a MyCalendarThree class to store your events. A new event can always be added. Your class ...
- [LeetCode] My Calendar II 我的日历之二
Implement a MyCalendarTwo class to store your events. A new event can be added if adding the event w ...
- 与众不同 windows phone (26) - Contacts and Calendar(联系人和日历)
原文:与众不同 windows phone (26) - Contacts and Calendar(联系人和日历) [索引页][源码下载] 与众不同 windows phone (26) - Con ...
- [LeetCode] 731. My Calendar II 我的日历之二
Implement a MyCalendarTwo class to store your events. A new event can be added if adding the event w ...
- Java基础知识强化94:Calendar类之Calendar概述和获取日历字段的方法
1. Calendar类概述: Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR.MONTH.DAY_OF_MONTH.HOUR 等 日历字段之间的转换提供了一些方法,并 ...
- LeetCode My Calendar I
原题链接在这里:https://leetcode.com/problems/my-calendar-i/description/ 题目: Implement a MyCalendar class to ...
- java 的Calendar类的可视化日历示例
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...
- java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容
8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character ...
- 通过学习Date和Calendar时写的日历
package com.etc.util; import java.util.Calendar; import java.util.Scanner; public class Calendar2 { ...
随机推荐
- 常用七大经典排序算法总结(C语言描述)
简介 其中排序算法总结如下: 一.交换排序 交换排序的基本思想都为通过比较两个数的大小,当满足某些条件时对它进行交换从而达到排序的目的. 1.冒泡排序 基本思想:比较相邻的两个数,如果前者比后者大,则 ...
- Java集合:HashMap源码剖析
一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null 之外,HashMap ...
- robotframework环境搭建问题
启动的时候报错,应该是环境变量没有配置好 错误: command: pybot.bat --argumentfile c:\users\keikei\appdata\local\temp\RIDEam ...
- [日常] 最近的一些破事w...
更新博文一篇以示诈尸(大雾 (其实只是断了个网然后就彻底失踪了一波w...连题解都没法写了QAQ) $ \tiny{诈尸的实际情况是老姚提前走还把十一机房门锁了然而钥匙在联赛的时候就还了于是并不能进去 ...
- 通过运行一个tomcat容器来记录下初学docker常用的几个命令---容器篇
1.查看容器列表 显示正在运行的容器: [root@localhost HMK]# docker ps 显示所有容器,包括未运行的: [root@localhost HMK]# docker ps - ...
- Beta No.1
一.今日任务 重新熟悉整体项目 对整个项目在未来的beta冲刺中进程有一个合理的规划 由于我们送出的是一个负责前端的成员,引入的也是一个负责前端工作的女生,(女生做起美工比起男生更加得心应手吧)所以我 ...
- C语言结构体作业
一.PTA实验作业 题目1:6-3 结构体数组中查找指定编号人员 1. 本题PTA提交列表 2. 设计思路 定义一个结构体指针*p for i=0 to i=7 如果std+i的编号与输入的编号一样 ...
- 201621123040《Java程序设计》第12周学习总结
1.本周学习总结 2.面向系统综合设计-图书馆管理系统或购物车 2.1简述如何使用流与文件改造你的系统.文件中数据的格式如何? 将书目信息写入文件,查阅图书馆书目信息时,实现文件的读取 2.2简述系统 ...
- fs检测文件夹状态
var http = require("http"); var fs = require("fs"); var server = http.createServ ...
- NOIP2016 天天爱跑步 正解
暴力移步 http://www.cnblogs.com/TheRoadToTheGold/p/6673430.html 首先解决本题应用的知识点: dfs序——将求子树的信息(树形)转化为求一段连续区 ...