题目重点:不是仅求最高并发,也不是仅X=1。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 半开区间start<end,目标X正整数;输出最大相接合并时间段。
- X0需有限查询域,否则两端无限空闲,本代码拒绝;同一人多重记录不自动去重。
解题路线
- 每开始+1结束−1,先把同timestamp delta合并。在相邻不同事件点[t,next)内active常数,若等X加入。
- 相接满足段合并:一个会议结束另一个开始净delta0,active仍X,可以连成更长段。不能把同点中间处理状态输出成正长度段。
- 与每person恰覆盖一次的题不同,这里每会议记录占一个单位。若要按人去重,必须先合并每人的重叠区间再扫描。
手动走一遍
[1,3)、[2,4),X1输出[1,2)和[3,4),X2输出[2,3)。[1,2)、[2,3),X1输出[1,3),中间无空隙。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from collections import defaultdict
def segments(intervals,target):
if target<=0:raise ValueError("positive target; zero needs a query domain")
events=defaultdict(int)
for a,b in intervals:
if a>=b:raise ValueError("positive-duration half-open interval")
events[a]+=1;events[b]-=1
times=sorted(events);active=0;answer=[]
for i,t in enumerate(times[:-1]):
active+=events[t];end=times[i+1]
if active==target:
if answer and answer[-1][1]==t:answer[-1]=(answer[-1][0],end)
else:answer.append((t,end))
return answer
复杂度
n会议O(nlogn)时间/O(n)事件及输出空间。
易错点与追问
容易失分的边界
- closed端点语义会有孤立点,不能不加说明套半开。
- 求≥X与==X输出不同。
继续深挖
- 在线add/delete时能否维护整条并发曲线?
- 按最大并发值返回所有段时怎样一遍或两遍扫描?
