题目

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相关推荐

  1. LeetCode 731. 我的日程安排表 II

    731. 我的日程安排表 II [分析]用两个TreeMap分别维护一重区间和二重区间,对于新加入的区间先检查是否在二重区间,不在的话循环检查一重区间的交集,把交集纳入二重区间,同时删除查找到的已经在 ...

  2. leetcode-每日一题731. 我的日程安排表 II

    题目链接:https://leetcode.cn/problems/my-calendar-ii/ 孪生弟弟题 729. 我的日程安排表 I:https://leetcode.cn/problems/ ...

  3. 力扣 731. 我的日程安排表 II

    题目来源:https://leetcode.cn/problems/my-calendar-ii/ 大致题意: 设计一个日程类 MyCalendar,包含以下功能: 有一个 book(int star ...

  4. LeetCode 732. 我的日程安排表 III(差分思想)

    文章目录 1. 题目 2. 解题 1. 题目 实现一个 MyCalendar 类来存放你的日程安排,你可以一直添加新的日程安排. MyCalendar 有一个 book(int start, int ...

  5. LeetCode 729. 我的日程安排表 I(set 二分查找)

    文章目录 1. 题目 2. 解题 2.1 set 二分查找 2.2 差分思想 1. 题目 实现一个 MyCalendar 类来存放你的日程安排.如果要添加的时间内没有其他安排,则可以存储这个新的日程安 ...

  6. java人员安排表_Java实现 LeetCode 732 我的日程安排表 III(暴力 || 二叉树)

    732. 我的日程安排表 III 实现一个 MyCalendar 类来存放你的日程安排,你可以一直添加新的日程安排. MyCalendar 有一个 book(int start, int end)方法 ...

  7. LeetCode实战:环形链表 II

    背景 为什么你要加入一个技术团队? 如何加入 LSGO 软件技术团队? 我是如何组织"算法刻意练习活动"的? 为什么要求团队的学生们写技术Blog 题目英文 Given a lin ...

  8. Leetcode 142. Linked List Cycle II

    地址:Leetcode 142. linked list Cycle II 问题描述:检测链表是否存在环,是的话返回环入口,否则返回None. 这道题有两个思路,一个是经典的快慢指针的思路,另外一个是 ...

  9. 【To Do】LeetCode 142. Linked List Cycle II

    LeetCode 142. Linked List Cycle II Solution1:我的答案 这道题多次遇到,牢记此解法 这道题要深思一下,快指针和慢指针的速度对比不同,会产生什么不同的结果? ...

最新文章

  1. RHEL6系列更换epel源
  2. 派生类构造函数和析构函数的执行顺序
  3. java byte 转 c_C 和 Java 之间的byte数据的转换问题
  4. linux 实现共享内存同步
  5. 在程序开发中怎样写SQL语句可以提高数据库的性能
  6. 在Windows 下如何使用 AspNetCore Api 和 consul
  7. 在一个字符串中找到第一个只出现一次的字符,并返回它的位置
  8. MySQL 数据库性能优化之缓存参数优化
  9. Linux vim 编辑文件底部显示[converted]解决办法
  10. 西北乱跑娃 --- bottle微框架从注册到应用(三)
  11. wordpress创建_如何在WordPress中创建专业的在线简历
  12. android wifi热点setting
  13. hdu2197 本源串
  14. 三菱伺服定长追剪,系统为Q172DSCPU,高级同步模式
  15. 应用层 DNS域名解析服务器 文件传送协议FTP 简单邮件传送协议SMTP 万维网 HTTP超文本协议
  16. 安装openKylin 开源操作系统 (ubuntukylin-22.04-pro-amd64.isowindows版)
  17. 程序员应该多久跳槽一次?为何贵圈跳槽如此频繁?
  18. ZOJ 3886 Nico Number(筛素数+Love(线)Live(段)树)
  19. openstack heat 编排模板(HOT)指南
  20. 【图形学】刚体的旋转

热门文章

  1. 使用wps2019 给目录加数字时出现按数字自动跳到上一行
  2. 希腊字母(广泛用于数学、物理、生物、天文等)!
  3. 汽车造型中 - A面是什么
  4. 【vue】axios和vue-axios请求模块
  5. 淘宝内容大爆炸:直播双12峰值超越双11
  6. 多测师肖sir_高级讲师_第二个月第2讲python之基本操作(002)
  7. pandas处理excel相关,插入折线图并保存xlsx文件用的,搬运一篇外网文章里的内容吧。
  8. java stop有实现吗_Java 如何实现优雅停服?刨根问底
  9. Premiere Pro之视频添加视频边框(十八)
  10. NX/UG二次开发—建模—关于创建单线汉字的三种思路