携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。
怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~
一、题目描述:
-
题目内容
-
题目示例
-
题目解析
0 <= start < end <= 109
- 每个测试用例,调用
book
方法的次数最多不超过1000
次。
二、思路分析:
我们拿到本题,读取题目要构建一个日程安排表,对于每一次预定时间范围[start,end]进行预定操作,当最新的时间断与已经预定的时间段重合时,则不能进行预定。我们来看一下日常安排表对象构成情况:
- Mycalendar类初始化日历对象
- 时间段[start,end]是半开区间的,start <= t < end
- book方法对时间段新的时间段[start,end]进行检查
对本题的内容进行了解后,解答本题我们可以直接使用模拟遍历方法解答即可,思路如下:
- MyCalendar对象初始化时,创建一个booklist列表存储已预定的时间段
- book方法中,需要判断[start,end]在booklist列表已预定的时间段是否有重合的
- 通过区间我们可以快速找到重合时间段的判断条件即 start < e and end > s
- 当时间段重合时,则直接返回False,反之则加入到booklist中并返回True
我们按照上述思路,可以快速使用Python代码来实现,代码如下:
class MyCalendar(object): def __init__(self): self.booklist = [] def book(self, start, end): """ :type start: int :type end: int :rtype: bool """ for s,e in self.booklist: if s < end and e > start: return False self.booklist.append([start,end]) return True 复制代码
对于一个列表中所有元素要求出指定位置之前的元素和,我们可以使用前缀和的思路,提前遍历列表把元素进行加法计算,在后续使用过程中,我们就可以直接取用,无需再进行繁琐的遍历列表了。
本题是涉及到区间判断的,我们会涉及到历史区间的遍历和更改,如果再使用前缀和,就能适用了。因此,涉及到新概念,线段树方法来实现。
- 线段树中节点,主要包含三个字段第一个是左右孩子和懒惰标记
- 线段树中主要的方法:build构建线段树、update更新线段树、query查询线段树
- 线段树中数据查询和更新的时间复杂度为O(log2n)
class MyCalendar(object): def __init__(self): self.tree = set() self.lazy = set() def query(self,start,end,l,r,idx): if r < start or end < l: return False if idx in self.lazy: return True if start <= l and r <= end: return idx in self.tree mid = (l + r) // 2 return self.query(start, end, l, mid, 2 * idx) or \ self.query(start, end, mid + 1, r, 2 * idx + 1) def update(self,start,end,l,r,idx): if r < start or end < l: return if start <= l and r <= end: self.tree.add(idx) self.lazy.add(idx) else: mid = (l + r) // 2 self.update(start, end, l, mid, 2 * idx) self.update(start, end, mid + 1, r, 2 * idx + 1) self.tree.add(idx) if 2 * idx in self.lazy and 2 * idx + 1 in self.lazy: self.lazy.add(idx) def book(self, start, end): """ :type start: int :type end: int :rtype: bool """ if self.query(start, end - 1, 0, 10 ** 9, 1): return False self.update(start, end - 1, 0, 10 ** 9, 1) return True 复制代码
三、总结:
本题考察我们对于区间数据更新与判断,对比直接遍历模拟,线段树对于区间内数据更新和查询是更优的解法,AC提交记录如下:
扫描二维码关注公众号,回复:
14439266 查看本文章
![](/qrcode.jpg)
- 时间复杂度:O(nlogC),其中 n为日程安排的数量。logC为线段树中查询最多的节点数
- 空间复杂度:O(nlogC),其中 n 为日程安排数量。logC为线段树中最多新增logC节点数
以上是本期内容,欢迎大佬们点赞评论,下期见~~~