[LeetCode]731. 我的日程安排表 II
题目
731. 我的日程安排表 II
731. 我的日程安排表 II
实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内不会导致三重预订时,则可以存储这个新的日程安排。MyCalendar 有一个 book(int start, int end)方法。它意味着在 start 到 end 时间内增加一个日程安排,注意,这里的时间是半开区间,即 [start, end), 实数 x 的范围为, start <= x < end。当三个日程安排有一些时间上的交叉时(例如三个日程安排都在同一时间内),就会产生三重预订。每次调用 MyCalendar.book方法时,如果可以将日程安排成功添加到日历中而不会导致三重预订,返回 true。否则,返回 false 并且不要将该日程安排添加到日历中。请按照以下步骤调用MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)示例: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
解释:
前两个日程安排可以添加至日历中。 第三个日程安排会导致双重预订,但可以添加至日历中。
第四个日程安排活动(5,15)不能添加至日历中,因为它会导致三重预订。
第五个日程安排(5,10)可以添加至日历中,因为它未使用已经双重预订的时间10。
第六个日程安排(25,55)可以添加至日历中,因为时间 [25,40] 将和第三个日程安排双重预订;
时间 [40,50] 将单独预订,时间 [50,55)将和第二个日程安排双重预订。提示:每个测试用例,调用 MyCalendar.book 函数最多不超过 1000次。
调用函数 MyCalendar.book(start, end)时, start 和 end 的取值范围为 [0, 10^9]。
解法
方法1:暴力
static class MyCalendarTwo {List<int[]> calendar;//维护是当前的预订区间List<int[]> overlaps;//维护的重叠的区间也就是说2个calendar区间中都出现了这个区间public MyCalendarTwo() {calendar = new ArrayList<>();overlaps = new ArrayList<>();}public boolean book(int start, int end) {//overlaps的区间与[start,end]有交集,说明当前的是三重预订,返回falsefor (int[] item : overlaps) {if (start < item[1] && end > item[0]) return false;}//遍历calendar 找重叠区间for (int[] item : calendar) {if (start < item[1] && end > item[0]) {overlaps.add(new int[]{Math.max(start, item[0]), Math.min(item[1], end)});}}calendar.add(new int[]{start, end});return true;}
}
方法2:TreeMap
有点差分的思想
static class MyCalendarTwo {TreeMap<Integer, Integer> map;public MyCalendarTwo() {map = new TreeMap<>();}public boolean book(int start, int end) {//思路有点类似差分数组,相当于[start,end)这个区间内的元素出现了一次,都+1map.put(start, map.getOrDefault(start, 0) + 1);map.put(end, map.getOrDefault(end, 0) - 1);int count = 0;for (Map.Entry<Integer, Integer> e : map.entrySet()) {count += e.getValue();//大于等于3次的预订次数的区间,需要恢复if (count >= 3) {map.put(start, map.getOrDefault(start, 0) - 1);if (map.get(start) == 0) {map.remove(start);//这一步不移除的也不影响程序正确性}map.put(end, map.getOrDefault(end, 0) + 1);if (map.get(end) == 0) {map.remove(end);}return false;}}return true;}
}
方法3:动态开点+懒标记线段树
class MyCalendarTwo {//然一个比较实用的估点方式可以「尽可能的多开点数」,利用题目给定的空间上界和我们创建的自定义类// (结构体)的大小,尽可能的多开( Java 的 128M 可以开到 5 * 10^6 以上)。class Node {int ls, rs;//分别代表当前节点的左右子节点在线段树数组 tr 中的下标int lazy;//懒标记int maxx;//当前区间的最大值}int N = (int) 1e9 + 10;int cnt = 1;//动态开点的下标int M = 120010;Node[] tr = new Node[M];//l,r 为当前节点存储的区间 L,R表示要修改的前,这个区间不会变,设置成大写void update(int u, int l, int r, int L, int R, int v) {//[l,r]区间被[L,R]覆盖if (L <= l && r <= R) {tr[u].maxx += v;tr[u].lazy += v;return;}lazyCreate(u);pushdown(u);int mid = l + r >> 1;if (L <= mid) update(tr[u].ls, l, mid, L, R, v);if (R > mid) update(tr[u].rs, mid + 1, r, L, R, v);pushup(u);}int query(int u, int l, int r, int L, int R) {if (L <= l && r <= R) return tr[u].maxx;lazyCreate(u);pushdown(u);int mid = l + r >> 1;int res = 0;if (L <= mid) res = Math.max(res, query(tr[u].ls, l, mid, L, R));if (R > mid) res = Math.max(res, query(tr[u].rs, mid + 1, r, L, R));return res;}void lazyCreate(int u) {if (tr[u] == null) {tr[u] = new Node();}if (tr[u].ls == 0) {tr[u].ls = ++cnt;tr[tr[u].ls] = new Node();}if (tr[u].rs == 0) {tr[u].rs = ++cnt;tr[tr[u].rs] = new Node();}}void pushup(int u) {tr[u].maxx = Math.max(tr[tr[u].ls].maxx, tr[tr[u].rs].maxx);}void pushdown(int u) {tr[tr[u].ls].lazy += tr[u].lazy;tr[tr[u].rs].lazy += tr[u].lazy;tr[tr[u].ls].maxx += tr[u].lazy;tr[tr[u].rs].maxx += tr[u].lazy;tr[u].lazy = 0;}public MyCalendarTwo() {}public boolean book(int start, int end) {int res = query(1, 1, N + 1, start + 1, end);if (res >= 2) return false;update(1, 1, N + 1, start + 1, end, 1);return true;}
}
[LeetCode]731. 我的日程安排表 II相关推荐
- LeetCode 731. 我的日程安排表 II
731. 我的日程安排表 II [分析]用两个TreeMap分别维护一重区间和二重区间,对于新加入的区间先检查是否在二重区间,不在的话循环检查一重区间的交集,把交集纳入二重区间,同时删除查找到的已经在 ...
- leetcode-每日一题731. 我的日程安排表 II
题目链接:https://leetcode.cn/problems/my-calendar-ii/ 孪生弟弟题 729. 我的日程安排表 I:https://leetcode.cn/problems/ ...
- 力扣 731. 我的日程安排表 II
题目来源:https://leetcode.cn/problems/my-calendar-ii/ 大致题意: 设计一个日程类 MyCalendar,包含以下功能: 有一个 book(int star ...
- LeetCode 732. 我的日程安排表 III(差分思想)
文章目录 1. 题目 2. 解题 1. 题目 实现一个 MyCalendar 类来存放你的日程安排,你可以一直添加新的日程安排. MyCalendar 有一个 book(int start, int ...
- LeetCode 729. 我的日程安排表 I(set 二分查找)
文章目录 1. 题目 2. 解题 2.1 set 二分查找 2.2 差分思想 1. 题目 实现一个 MyCalendar 类来存放你的日程安排.如果要添加的时间内没有其他安排,则可以存储这个新的日程安 ...
- java人员安排表_Java实现 LeetCode 732 我的日程安排表 III(暴力 || 二叉树)
732. 我的日程安排表 III 实现一个 MyCalendar 类来存放你的日程安排,你可以一直添加新的日程安排. MyCalendar 有一个 book(int start, int end)方法 ...
- LeetCode实战:环形链表 II
背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given a lin ...
- Leetcode 142. Linked List Cycle II
地址:Leetcode 142. linked list Cycle II 问题描述:检测链表是否存在环,是的话返回环入口,否则返回None. 这道题有两个思路,一个是经典的快慢指针的思路,另外一个是 ...
- 【To Do】LeetCode 142. Linked List Cycle II
LeetCode 142. Linked List Cycle II Solution1:我的答案 这道题多次遇到,牢记此解法 这道题要深思一下,快指针和慢指针的速度对比不同,会产生什么不同的结果? ...
最新文章
- RHEL6系列更换epel源
- 派生类构造函数和析构函数的执行顺序
- java byte 转 c_C 和 Java 之间的byte数据的转换问题
- linux 实现共享内存同步
- 在程序开发中怎样写SQL语句可以提高数据库的性能
- 在Windows 下如何使用 AspNetCore Api 和 consul
- 在一个字符串中找到第一个只出现一次的字符,并返回它的位置
- MySQL 数据库性能优化之缓存参数优化
- Linux vim 编辑文件底部显示[converted]解决办法
- 西北乱跑娃 --- bottle微框架从注册到应用(三)
- wordpress创建_如何在WordPress中创建专业的在线简历
- android wifi热点setting
- hdu2197 本源串
- 三菱伺服定长追剪,系统为Q172DSCPU,高级同步模式
- 应用层 DNS域名解析服务器 文件传送协议FTP 简单邮件传送协议SMTP 万维网 HTTP超文本协议
- 安装openKylin 开源操作系统 (ubuntukylin-22.04-pro-amd64.isowindows版)
- 程序员应该多久跳槽一次?为何贵圈跳槽如此频繁?
- ZOJ 3886 Nico Number(筛素数+Love(线)Live(段)树)
- openstack heat 编排模板(HOT)指南
- 【图形学】刚体的旋转
热门文章
- 使用wps2019 给目录加数字时出现按数字自动跳到上一行
- 希腊字母(广泛用于数学、物理、生物、天文等)!
- 汽车造型中 - A面是什么
- 【vue】axios和vue-axios请求模块
- 淘宝内容大爆炸:直播双12峰值超越双11
- 多测师肖sir_高级讲师_第二个月第2讲python之基本操作(002)
- pandas处理excel相关,插入折线图并保存xlsx文件用的,搬运一篇外网文章里的内容吧。
- java stop有实现吗_Java 如何实现优雅停服?刨根问底
- Premiere Pro之视频添加视频边框(十八)
- NX/UG二次开发—建模—关于创建单线汉字的三种思路