用集合set极简实现,空间复杂度伪O(1)
class Solution: def minNumberDisappeared(self , nums: List[int]) -> int: # 哈希表,只需要存键,直接用集合 h = set() # 把数组元素弹出到集合 while nums: h.add(nums.pop()) # 让i从零向上增加,遇到的第一个不存在与集合中的i就是待求值。 i = 1 while i in h: i += 1 return i# 借鉴求1-n不重复数的思路,遍历数组,将原数组值分别与下标+1对应,如果不对应就交换。
交换的时候如果目标位置已经存在值,表示该值重复了,置为-1,让后面的操作忽略该数。
交换完成后当前位置的值要么为i+1,要么为无关紧要的值(范围之外的值)——后面遇到满足要求的值会填上的,以保证不会漏掉满足要求的值
class Solution:
def minNumberDisappeared(self , nums: List[int]) -> int:
i = 0
while i < len(nums): # 遍历数组,让值与下标+1对应
if nums[i] == i + 1: # 值与下标对应,遍历下一个元素
i += 1
else:
if 1 <= nums[i] <= len(nums): # 值小于等于0或者大于len(nums)一定不会与下标+1对应,忽略
k = nums[i]-1 # 根据值找到下标,值=下标+1
if nums[k] == nums[i]: # 如果下标处的值已经满足要求,表示该值重复,标为-1
nums[i] = -1
else: # 交换当前值与由当前值计算出的下标位置处的值
nums[i], nums[k] = nums[k], nums[i]
if nums[i] != i +1 or 1 <= nums[i] <= len(nums):
i -= 1 # 如果交换来的值恰好满足nums[i] = i +1,皆大欢喜
i += 1 # 如果不满足,原地继续交换,当然如果如果交换来的值在范围之外也可以跳出——后面遇到满足要求的值会填上的
for i in range(len(nums)):
if nums[i] != i+1: # 找第一个值不等于下标+1
return i+1
else:
return nums[i] + 1 # 如果都满足,最小正数为nums[i] + 1