leetcode 731. 我的日程安排表 II

实现一个程序来存放你的日程安排。如果要添加的时间内不会导致三重预订时,则可以存储这个新的日程安排。

当三个日程安排有一些时间上的交叉时(例如三个日程安排都在同一时间内),就会产生 三重预订

事件能够用一对整数 startTimeendTime 表示,在一个半开区间的时间 [startTime, endTime) 上预定。实数 x 的范围为 startTime <= x < endTime

实现 MyCalendarTwo 类:

  • MyCalendarTwo() 初始化日历对象。
  • boolean book(int startTime, int endTime) 如果可以将日程安排成功添加到日历中而不会导致三重预订,返回 true。否则,返回 false 并且不要将该日程安排添加到日历中。

示例 1:

复制代码
输入:
["MyCalendarTwo", "book", "book", "book", "book", "book", "book"]
[[], [10, 20], [50, 60], [10, 40], [5, 15], [5, 10], [25, 55]]
输出:
[null, true, true, true, false, true, true]

解释:
MyCalendarTwo myCalendarTwo = new MyCalendarTwo();
myCalendarTwo.book(10, 20); // 返回 True,能够预定该日程。
myCalendarTwo.book(50, 60); // 返回 True,能够预定该日程。
myCalendarTwo.book(10, 40); // 返回 True,该日程能够被重复预定。
myCalendarTwo.book(5, 15);  // 返回 False,该日程导致了三重预定,所以不能预定。
myCalendarTwo.book(5, 10); // 返回 True,能够预定该日程,因为它不使用已经双重预订的时间 10。
myCalendarTwo.book(25, 55); // 返回 True,能够预定该日程,因为时间段 [25, 40) 将被第三个日程重复预定,时间段 [40, 50) 将被单独预定,而时间段 [50, 55) 将被第二个日程重复预定。

提示:

  • 0 <= start < end <= 10^9
  • 最多调用 book 1000 次。

分析:第 729 题的进阶版本,区间需要重复三次才不能预定。由于 book 最多调用1000次,因此还是可以用直接遍历的方法来解决这道题。

相应地需要修改 MyCalendarTwo,除了记录可以被预定的日程,还需要记录已经被预定过两次的区间。对于每次预定,首先在已经预定过两次的区间上查询,如果存在交集,说明不能够预定;否则可以预定,把这次预定的区间,以及这次预定的区间与之前预定的区间所产生的重复预定区间存下来。

cpp 复制代码
typedef struct {
    int booksize;
    int *book;
    int overlapsize;
    int *overlop;
} MyCalendarTwo;


MyCalendarTwo* myCalendarTwoCreate() {
    MyCalendarTwo *my=(MyCalendarTwo*)malloc(sizeof(MyCalendarTwo));
    my->booksize=my->overlapsize=0;
    my->book=(int*)malloc(sizeof(int)*2020);
    my->overlop=(int*)malloc(sizeof(int)*2020);
    return my;
}

bool myCalendarTwoBook(MyCalendarTwo* obj, int startTime, int endTime) {
    for(int i=0;i<obj->overlapsize;i++)
        if(startTime<obj->overlop[i*2+1]&&endTime>obj->overlop[i*2])
            return false;

    for(int i=0;i<obj->booksize;i++)
    {
        if(startTime<obj->book[i*2+1]&&endTime>obj->book[i*2])
        {
            obj->overlop[obj->overlapsize*2]=fmax(obj->book[i*2],startTime);
            obj->overlop[obj->overlapsize*2+1]=fmin(obj->book[i*2+1],endTime);
            obj->overlapsize++;
        }
    }
    obj->book[obj->booksize*2]=startTime;
    obj->book[obj->booksize*2+1]=endTime;
    obj->booksize++;
    return true;
}

void myCalendarTwoFree(MyCalendarTwo* obj) {
    free(obj->book);
    free(obj->overlop);
    free(obj);
    return;
}

/**
 * Your MyCalendarTwo struct will be instantiated and called as such:
 * MyCalendarTwo* obj = myCalendarTwoCreate();
 * bool param_1 = myCalendarTwoBook(obj, startTime, endTime);
 
 * myCalendarTwoFree(obj);
*/
相关推荐
_dindong4 小时前
基础算法:滑动窗口
数据结构·学习·算法·leetcode·力扣
nju_spy9 小时前
力扣每日一题(二)任务安排问题 + 区间变换问题 + 排列组合数学推式子
算法·leetcode·二分查找·贪心·排列组合·容斥原理·最大堆
代码对我眨眼睛9 小时前
226. 翻转二叉树 LeetCode 热题 HOT 100
算法·leetcode·职场和发展
黑色的山岗在沉睡10 小时前
LeetCode 494. 目标和
算法·leetcode·职场和发展
小欣加油19 小时前
leetcode 62 不同路径
c++·算法·leetcode·职场和发展
夏鹏今天学习了吗19 小时前
【LeetCode热题100(38/100)】翻转二叉树
算法·leetcode·职场和发展
夏鹏今天学习了吗19 小时前
【LeetCode热题100(36/100)】二叉树的中序遍历
算法·leetcode·职场和发展
Mr.Ja20 小时前
【LeetCode热题100】No.11——盛最多水的容器
算法·leetcode·贪心算法·盛水最多的容器
微笑尅乐1 天前
从暴力到滑动窗口全解析——力扣8. 字符串转换整数 (atoi)
算法·leetcode·职场和发展
zycoder.2 天前
力扣面试经典150题day1第一题(lc88),第二题(lc27)
算法·leetcode·面试