题目重点:判断数组能否完全拆成值相等的二元组,以奇偶翻转集合 O(n) 检验,并处理空数组及负数。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版需要把所有元素恰好使用一次,任意两项若值相同即可成一对,不要求原数组相邻。
- 空数组返回 True(零对恰好覆盖零元素);若产品语义要求至少一对,应额外加非空判断。
- 整数可为负,等值以精确整数比较;没有排序或输出具体配对的要求。
解题路线
- 必要性:某个值出现次数为奇数,则相同值两两取走后必剩一个,无法完全配对。
- 充分性:若每个值出现次数为偶数,就对该值任意两项配对,直到用尽;不同值之间不相互依赖。
- 遍历时用集合保存当前出现次数为奇数的值:第一次加入、第二次移除,末尾集合为空当且仅当所有频次偶数。若还要输出下标对,用 value→未配对下标映射。
手动走一遍
[1,2,2,1] 的奇频集合依次为 {1}、{1,2}、{1}、{},返回 True;[1,1,2,2,2] 最后剩 {2},返回 False。连续重复并非必要条件,[1,2,1,2] 同样可配。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
"""Training contract: every array element must belong to an equal-value pair."""
def can_pair_equal_values(values: list[int]) -> bool:
odd = set()
for value in values:
if value in odd:
odd.remove(value)
else:
odd.add(value)
return not odd
复杂度
n 个元素、d 个不同值:预期 O(n) 时间、O(d) 空间;哈希退化最坏情况由运行环境的集合实现决定。排序后扫相邻二项可用 O(n log n) 时间和依排序实现的额外空间。
易错点与追问
容易失分的边界
- 只检查数组总长度为偶数,忽略每个值各自的奇偶性。
- 误以为只能配相邻元素。
- 把空数组定义为 False 却没有先说明题目是否要求至少一对。
- 值域未知时用固定范围数组计数。
继续深挖
- 若要返回每对原始下标,怎样在线性时间构造?
- 若配对条件改为两数和等于目标,奇偶计数为何不再足够?
- 流式输入到任意时刻查询是否全可配,奇频集合如何维护?
