北京一大厂员工被裁,拿到了56万赔偿。其媳妇太兴奋,在某平台发图分享喜悦,结果截图里公司名称没打码。
刚刷到这个,真给我看愣了。
北京某大厂员工被裁,拿了56万赔偿,本来这事到这儿也算体面退场。结果他媳妇太高兴,直接把赔偿截图发网上了,关键公司名字还没打码。
等反应过来删帖,已经晚了,截图到处传。公司、部门、姓名,全被同事给扒出来了。
56万还没捂热乎,先喜提全公司围观。大哥估计人都麻了,自己被裁没崩,回家一看网上全是自己……
数组里一个数重复了,一个数消失了:Python 解「错误的集合」
数组是 [1, 2, 2, 4],长度为 4,按规矩里面应该放着 1、2、3、4。
结果 2 出现了两次,3 直接没了。
这题叫“错误的集合”,要求返回:
[重复的数字, 缺失的数字]
题目本身不绕,真正容易写乱的是:一边找重复值,一边又想算缺失值,最后循环里塞了一堆判断。我的习惯是把两件事拆开。先把出现过的数字记下来,重复值自然会撞出来;再从 1 扫到 n,谁没出现,谁就是缺失值。
代码不用写得太花:
from typing import List
classSolution:
deffindErrorNums(self, nums: List[int]) -> List[int]:
appeared = [False] * (len(nums) + 1)
repeated = -1
for value in nums:
if appeared[value]:
repeated = value
continue
appeared[value] = True
missing = -1
for value in range(1, len(nums) + 1):
ifnot appeared[value]:
missing = value
break
return [repeated, missing]
拿 [1, 2, 2, 4] 跑一遍。
第一次遇到 2,把 appeared[2] 标记成 True。第二次再遇到 2,对应位置已经被标记过,重复数字就是它。
接着检查 1 到 4:
1:出现过
2:出现过
3:没有出现
4:出现过
所以最终返回:
[2, 3]
这里数组长度要开成 n + 1,因为数字范围是 1 到 n,下标 0 根本不用。这个地方少开一位,碰到数字 n 就会直接越界,属于很低级但很常见的错误。
再补一个边界数据:
nums = [2, 2]
长度为 2,完整集合应该是 [1, 2]。现在 2 重复,1 缺失,结果就是:
[2, 1]
这套写法的时间复杂度是 O(n)。前面遍历一次数组,后面再扫描一次数字范围,没有嵌套循环。空间复杂度也是 O(n),额外用了一个布尔数组。
有人会直接写:
for value in range(1, len(nums) + 1):
if value notin nums:
...
这段看着短,我一般不会这么交。value not in nums 每次都要重新扫描数组,外层再跑 n 次,整体会退化成 O(n²)。数据小的时候看不出区别,数据一大,耗时就不太好看了。
算法题里,代码短不是目的。循环里有没有偷偷重复扫描数据,这个才值得盯一下。