732. 我的日程安排表 III
原始题目链接:https://leetcode.cn/problems/my-calendar-iii/
当 k 个日程安排有一些时间上的交叉时(例如 k 个日程安排都在同一时间内),就会产生 k 次预订。
给你一些日程安排 [start, end) ,请你在每个日程安排添加后,返回一个整数 k ,表示所有先前日程安排会产生的最大 k 次预订。
实现一个 MyCalendarThree 类来存放你的日程安排,你可以一直添加新的日程安排。
MyCalendarThree() 初始化对象。
int book(int start, int end) 返回一个整数 k ,表示日历中存在的 k 次预订的最大值。
示例:
输入:
[“MyCalendarThree”, “book”, “book”, “book”, “book”, “book”, “book”]
[[], [10, 20], [50, 60], [10, 40], [5, 15], [5, 10], [25, 55]]
输出:
[null, 1, 1, 2, 3, 3, 3]
解释:
MyCalendarThree myCalendarThree = new MyCalendarThree();
myCalendarThree.book(10, 20); // 返回 1 ,第一个日程安排可以预订并且不存在相交,所以最大 k 次预订是 1 次预订。
myCalendarThree.book(50, 60); // 返回 1 ,第二个日程安排可以预订并且不存在相交,所以最大 k 次预订是 1 次预订。
myCalendarThree.book(10, 40); // 返回 2 ,第三个日程安排 [10, 40) 与第一个日程安排相交,所以最大 k 次预订是 2 次预订。
myCalendarThree.book(5, 15); // 返回 3 ,剩下的日程安排的最大 k 次预订是 3 次预订。
myCalendarThree.book(5, 10); // 返回 3
myCalendarThree.book(25, 55); // 返回 3
解题思路:
题目要求计算的是,每个新的日程时间表安排后,会产生的最大 k
次预订的值,那么在每次新添加日常后就需要统计当前的最大k次预定的值。使用一个计数器数据结构,开始时间start设置+1,结束时间设置-1,这样在目前的所以会议中,加入新的会议,并且符合交叉的情况的时候,就+1,如果会议结束就-1,由于是时间序列问题,所以需要从大到小排序,并且是每次加入新的安排都要排序。
代码实现:
class MyCalendarThree:
def __init__(self):
# 定义一个计数器,key是开始时间start和end,value分别是1和-1
# 巧妙的是1和-1的设置,这样唯一的日程时间对可以抵消计数为0
# 并且这是时间序列问题,所以需要排序,每次加入新的时间对都需要排序
self.time = collections.Counter()
def book(self, start: int, end: int) -> int:
# 1表示会议开始
self.time[start] += 1
# -1表示会议结束
self.time[end] -= 1
cur_max = ans = 0
# 因为是时间序列问题,所以每次都需要排序
for i in sorted(self.time):
# 用一个变量记录在当前有效时间里的最大k次预定
# 当前会议还没结束又有新的会议在时间上交叉预定时,就会一直是+1状态
# 如果当前其中有一个会议结束,那么是-1状态
# 所以每次新加入会议安排时,都需要统计cur_max,得出当前的最大k次预定值
cur_max += self.time[i]
if cur_max > ans:
ans = cur_max
return ans
# Your MyCalendarThree object will be instantiated and called as such:
# obj = MyCalendarThree()
# param_1 = obj.book(start,end)
参考文献:
https://leetcode.cn/problems/my-calendar-iii/solution/wo-de-ri-cheng-an-pai-biao-iii-by-leetcode/