找重复数字,用set就结束了?这道校招题还能追问三层

举报
霍格沃兹测试开发学社 发表于 2026/09/20 12:38:23 2026/09/20
【摘要】 先看这组数:7、3、7、3、7。如果题目说“找出重复数字”,你会返回什么?7和3?每个数各出现几次?还是所有重复出现的位置?这几种答案都可能符合某一种需求,但它们不是同一个函数。用一道模拟面试题往下拆,最值得展示的第一项能力,就是在动手写代码前,把“重复”的输出定义问清楚。第一层:你求的是重复的值,还是重复的次数对刚才的输入,几个结果分别是:要回答的问题本例结果哪些值出现超过一次7、3每个重...
先看这组数:7、3、7、3、7。

如果题目说“找出重复数字”,你会返回什么?7和3?每个数各出现几次?还是所有重复出现的位置?

这几种答案都可能符合某一种需求,但它们不是同一个函数。

用一道模拟面试题往下拆,最值得展示的第一项能力,就是在动手写代码前,把“重复”的输出定义问清楚。

第一层:你求的是重复的值,还是重复的次数

对刚才的输入,几个结果分别是:

要回答的问题
本例结果
哪些值出现超过一次
7、3
每个重复值出现几次
7出现3次,3出现2次
除首次出现外,多了几次
一共3次
哪些位置属于重复值
需要返回与原输入对应的位置

直接写set只会得到不同的值,无法单靠这个结果知道哪些值重复。len(values) - len(set(values))能计算多出来的出现次数,也不能告诉你每个值重复了几次


先约定本次函数:输入只接受整数,不把布尔值算作整数;输出所有出现超过一次的值,按它们在输入中首次出现的顺序排列。

from collections import Counter

def duplicated_values(values):
    counts = Counter()
    for value in values:
        if type(value) is not int:
            raise ValueError("只接受整数,不接受布尔值")
        counts[value] += 1
    return [value for value, count in counts.items() if count > 1]

assert duplicated_values([73737]) == [73]
assert duplicated_values([]) == []
assert duplicated_values([2332]) == [23]

这里利用Counter保存首次插入顺序的行为。最后一个断言有意区分两种顺序:首次出现顺序是2、3,首次“被发现重复”的顺序却是3、2。

如果题目没有要求输出顺序,也应说清自己的选择,避免测试和实现各自假定一种口径。

第二层:输入里混进True,为什么结果可能变了

Python里,True与1的相等比较为真,布尔值也属于int的子类。若直接把它们放进依赖相等性与哈希的计数结构,就可能被视为同一个键。

所以示例没有用isinstance(value, int),而是明确排除了布尔值。这不是说所有产品都必须这样做,而是当前函数契约只接受严格的整数输入。

还可以继续问:负数算不算合法?是否允许空输入?数字字符串"7"与整数7是不是同一项?如果业务处理的是编号,前导零是否有意义?

这些问题不需要全部塞进一个算法题里,但你应该知道,选择一种数据结构之前,先要知道业务认为什么东西相等。

测试样本可以这样准备:

  • 全部不同,检查没有误报。
  • 一个值多次出现,检查只输出一次。
  • 多个重复值交错出现,检查计数与顺序。
  • 空输入、负数和零,按已确认契约验收。
  • 布尔值、字符串等非约定类型,明确拒绝或明确转换。

第三层:数据放不进内存,还能不能这么做

对可哈希的普通整数,在通常的哈希表条件下,计数方案的期望时间随输入规模线性增长;空间主要取决于不同值的数量。

“线性时间”不代表不用考虑内存。几亿个不同值各保留一个计数,字典本身也需要空间。生成器可以避免一次性保存全部输入,却不能让计数表凭空消失。

如果数据已经排序,可以逐组统计相邻相同值;如果输入远大于内存,可以考虑外部排序后分组,或者按稳定规则分区,再在每个分区内计数。分区方案仍要处理倾斜和过大的分区,不能只说“哈希一下就行”。

若业务只需要判断“可能见过没有”,某些近似结构可能有用;但如果要求精确列出重复值,就不能把有误判概率的结果直接当成最终答案。

AI能秒写函数,你要能说出它漏了哪个条件

让AI写找重复数字的代码并不难。更能体现测试开发思路的练习,是拿同一份输入定义去核验它:输出值还是次数,顺序如何处理,非法类型怎么办,数据规模变化后还有什么限制。

可以把问题分成三步回答:

“我先确认重复的定义和输出顺序。对可放进内存的输入,用计数表统计,再按约定返回结果。如果规模很大,会评估不同值数量和可用内存,再选择排序或分区方案,并保留对应的异常与边界测试。”

这段回答的价值,在于每一步都能继续展开一个例子。面试官换一组数据,你仍然知道自己在验证什么。

下次遇到看起来只有一行set的题,先写出一个你认为正确的输入输出对。把问题说清楚,代码才有办法写对。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。