SWE · Coding

每日Job同类型重叠共享:按类型并集计算峰值容量

相同Job重叠允许共享,与每个实例独占Server是两种模型。

题目重点:相同Job重叠允许共享,与每个实例独占Server是两种模型。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 每个(type,start,duration)每天周期P重复;相同type重叠合并忙区间,duration≥P则该type全天忙。
  • 代码返回同时活跃不同type的峰值容量,允许时刻边界无代价迁移/重新分配。若Job必须固定绑定物理Server全程不迁移,循环区间着色另求,不能把峰值直接当充分答案。

解题路线

  1. 每条周期区间切为[0,P)内一段或跨午夜两段;同type先合并重叠及相接,不能跨类型合并。
  2. 各type并集端点加+1/−1,同时间合并事件后求峰值;半开端点结束即释放,不多算瞬间重叠。长于一天同type的重复覆盖完整周期,只需要一个同时活跃类型计数。
  3. 固定绑定模型的循环弧可能形成三个类型两两相交却无三者同点,峰值2但冲突图需3色。若面试要求最少固定Server,必须解决该模型或明确可切段调度条件。

手动走一遍

A从22持续4、P24,切[22,24)+[0,2);另一A从0持续1合并,不多占。A持续30≥24全天忙,B只[4,5)忙,峰值2。不同类型实例仍不能合并。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from collections import defaultdict

def servers(jobs,period):
    # Repeating (job_type, start, duration), same type overlaps share one server.
    if period<=0:raise ValueError("positive period")
    by_type=defaultdict(list)
    for job,start,duration in jobs:
        if duration<0:raise ValueError("negative duration")
        if duration==0:continue
        start%=period
        if duration>=period:by_type[job].append((0,period));continue
        end=start+duration
        if end<=period:by_type[job].append((start,end))
        else:by_type[job].extend(((start,period),(0,end-period)))
    events=defaultdict(int)
    for intervals in by_type.values():
        merged=[]
        for a,b in sorted(intervals):
            if merged and a<=merged[-1][1]:merged[-1]=(merged[-1][0],max(b,merged[-1][1]))
            else:merged.append((a,b))
        for a,b in merged:events[a]+=1;events[b]-=1
    active=answer=0
    for time in sorted(events):active+=events[time];answer=max(answer,active)
    return answer

复杂度

n记录排序并集O(nlogn)、事件O(nlogn),空间O(n);峰值容量不含固定绑定着色结果。

易错点与追问

容易失分的边界

  • 单独把跨日切段视独立Job会给同type重复计数。
  • 固定绑定约束下用并发峰值承诺最少Server可能错误。

继续深挖

  • 若同type有两个版本且不能共享,如何构造真正合并键?
  • 禁止迁移时如何从区间冲突图给下界、可行上界及小规模精确解?
✓已复制微信号!