题目重点:区分重复值、重复记录和多余次数,双集合保证单次输出,并明确结果顺序。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练输入hashable值,等值按语言相等/hash合同。返回出现至少两次的不同值。
- 结果按第二次出现顺序;这是训练选择,题目未指定顺序。业务对象须先确定key/字段标准化,不能擅自整行字符串去重。
解题路线
- seen记录已见,emitted记录已输出。读到值已seen且未emitted时加入结果与emitted;无论是否重复都更新seen。
- 首次不输出、第二次恰好一次、第三次以后被emitted挡住,因此每个重复值输出一次。一个seen集合只知道重复,无法避免第三次重复输出。
- 二次遍历Counter也正确,若按首次出现顺序输出更自然;如果要求排序结果,则在unique结果上排序并说明代价。
- 流式无界输入的精确去重需要记住所有不同值;Bloom filter有误判,不可直接用来保证精确结果,除非有后端验证或业务接受近似。
手动走一遍
[b,a,a,b,a,c]返回[a,b],按第二次出现顺序;不是[a,b,a]也不是次数{a:3,b:2}。空输入与全唯一返回[]。9,841组三值数组与独立计数/第二次位置排序对照通过。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def duplicate_values(values):
"""Hashable keys; return each repeated value once, in second-occurrence order."""
seen, emitted, result = set(), set(), []
for value in values:
if value in seen and value not in emitted:
emitted.add(value)
result.append(value)
seen.add(value)
return result
复杂度
期望O(n)时间、O(u)辅助状态与O(r)输出,u为不同值数,r为重复不同值数;哈希碰撞最坏不是保证线性。
易错点与追问
容易失分的边界
- 每次重复都append。
- 把输出unique误解为只保留出现一次的值。
- 对象去重没定义key。
- 忽略输出顺序合同。
继续深挖
- 按首次出现顺序返回如何改?
- 只能O(1)空间且允许修改数组有哪些额外范围约束?
- 跨机器的重复检测怎样按key分区?
