题目详情
给你一个未排序的整数数组 nums
,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n)
并且只使用常数级别额外空间的解决方案。
示例 1:
输入:nums = [1,2,0]
输出:3
解释:范围 [1,2] 中的数字都在数组中。
示例 2:
输入:nums = [3,4,-1,1]
输出:2
解释:1 在数组中,但 2 没有。
示例 3:
输入:nums = [7,8,9,11,12]
输出:1
解释:最小的正数 1 没有出现。
提示:1 <= nums.length <= 10^5
-2^31 <= nums[i] <= 2^31 - 1
做题思路
因为要查找的是缺失第一个的正数,所以可以知道返回值最小为1,最大为数组长度+1。那么我们可以将数组中的正数放到数组的索引位置,然后进行对比索引是否等于数组中的数字,如果不满足,则返回此数字。
举例
nums = [3, 4, -1, 1],第一次遍历将正数放到对应索引位置(为了方便对比,我们对数组的左边添加一个元素0)即nums = [0, 3, 4,- 1, 1]。
遍历得到nums = [0, 1, -1, 3, 4]
所以再次遍历可到第一个缺失的数字为2。
因为要求的时间复杂度为O(n)
,空间复杂度为O(1)
。所以就是如何在原数组进行处理的问题。
方法
- 遍历数组如果是正数,并且索引位置数字不满足条件,就将数字索引位置数字进行交换。
- 如果不是,则index+=1。
代码
class Solution:
def firstMissingPositive(self, nums: List[int]) -> int:
"""
将位置变换
将0 < nums[i] <= len(nums)的数字放到自己的位置上
:param nums:
:return:
"""
if not nums:
return 1
nums = [0] + nums
i = 1
while i < len(nums):
if 0 < nums[i] < len(nums) and nums[nums[i]] != nums[i]: # 第一个条件
tmp = nums[nums[i]]
nums[nums[i]] = nums[i]
nums[i] = tmp
else: # 第二个条件
i += 1
continue
# 返回结果
for i in range(1, len(nums)):
if i != nums[i]:
return i
return len(nums)