本题解使用了两次遍历。第一次遍历数组,利用负号标记法找出重复的元素。具体做法是,遍历到某个元素 nums[i] 时,将 nums[abs(nums[i])-1] 取反。如果发现取反后的值为负数,说明之前已经遍历过该位置,即 abs(nums[i]) 就是重复的元素。第二次遍历数组,找出仍为正数的位置 i,说明 i+1 就是缺失的数字。
时间复杂度: O(n)
空间复杂度: O(1)
class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
dup = 0
miss = 0
n = len(nums)
# 确定重复元素
# 注意索引偏移
for i in range(n):
j = abs(nums[i])
# 如果 nums[j-1] 已经是负数,说明之前遍历过,j 就是重复元素
if nums[j-1] < 0:
dup = j
# 否则将 nums[j-1] 取反,标记该位置已遍历过
else:
nums[j-1] *= -1
# 确定缺失元素
for i in range(n):
# 如果 nums[i] 仍为正数,说明 i+1 是缺失的数字
if nums[i] > 0:
miss = i+1
break
return [dup, miss] if dup and miss else []