题目重点:为每个固定长度K窗口判断是否有任意重复值,区分指定值T和距离追问。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练1≤K≤N,输出每个完整K窗口的bool列表;重复是至少两次同值,不限定T。空/过大窗口作为非法输入。
- 指定T且两位置距离严格<K是另一问法,可以共享滑窗思想但输出不同,不能只检查T回答本题。
解题路线
- counts维护当前窗口每值次数,duplicateKeys维护count≥2的值有多少。新值计数1→2时加1,2→3不再加;出窗2→1减1,3→2保持。
- right加入并移除right−K的旧元素后,窗口恰好K个;duplicateKeys>0即有重复。完整窗口之前不输出。
- 为什么只关心跨2?重复存在条件是某count至少2,不是重复对数;三次同值仍只有一个重复key,用总duplicate occurrence另一种公式也行但不能混合。
- 删计数0键让空间不随全部历史不同值增长。哈希值需要可hash,若是对象要明确身份/相等语义。
手动走一遍
[1,2,1,3]、K3输出[True,False];[1,1,1]、K2两个窗口都True,移出一个1时count3→2不应把重复标记清掉。K1全部False。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from collections import defaultdict
def duplicate_windows(values,k):
"""One bool per exactly k-length window, any repeated value; 1<=k<=n."""
if not 1<=k<=len(values):raise ValueError('invalid window size')
counts=defaultdict(int);duplicate_keys=0;result=[]
for i,value in enumerate(values):
counts[value]+=1
if counts[value]==2:duplicate_keys+=1
if i>=k:
old=values[i-k]
if counts[old]==2:duplicate_keys-=1
counts[old]-=1
if counts[old]==0:del counts[old]
if i>=k-1:result.append(duplicate_keys>0)
return result
复杂度
均摊O(N)时间、O(K)状态、O(N−K+1)输出;每步两键更新,不每窗建set重新扫描O(NK)。
易错点与追问
容易失分的边界
- 出窗只要同值计数下降就减少duplicateKeys,会漏仍重复的3→2。
- 只在完整窗口出现后才移旧元素,窗口长度可能多1。
继续深挖
- 如果只要判断是否存在任意重复窗口,可命中早退;输出每窗则不能。
- 固定K改可变最长无重复窗口时,left收缩规则与输出怎样变?
