SDE · Phone Coding

Amazon Coding:返回重复数据,每个值只输出一次

区分重复值、重复记录和多余次数,双集合保证单次输出,并明确结果顺序。

题目重点:区分重复值、重复记录和多余次数,双集合保证单次输出,并明确结果顺序。

题意与假设

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

  • 训练输入hashable值,等值按语言相等/hash合同。返回出现至少两次的不同值。
  • 结果按第二次出现顺序;这是训练选择,题目未指定顺序。业务对象须先确定key/字段标准化,不能擅自整行字符串去重。

解题路线

  1. seen记录已见,emitted记录已输出。读到值已seen且未emitted时加入结果与emitted;无论是否重复都更新seen。
  2. 首次不输出、第二次恰好一次、第三次以后被emitted挡住,因此每个重复值输出一次。一个seen集合只知道重复,无法避免第三次重复输出。
  3. 二次遍历Counter也正确,若按首次出现顺序输出更自然;如果要求排序结果,则在unique结果上排序并说明代价。
  4. 流式无界输入的精确去重需要记住所有不同值;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分区?
✓已复制微信号!