题目
给你一个未排序的整数数组 nums
,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n)
并且只使用常数级别额外空间的解决方案。
解题思路
常规 map
方法需要用到 O(n)
的复杂度,不做赘述。题目要找到最小的正整数,利用 map
的思想,可以让数组下标作为键值,数组下标对应的元素为值构建构造关系,这样进行遍历就可以很容易找到缺失的正数。现在问题就变成了如何构建这样的数组。我们需要对数组中所有的元素进行归位,遇到 num[i]
如果在正数范围内,那么就让他与 num[num[i] - 1]
交换(数组下标从0开始,值从1开始,所以需要-1),这样 num[num[i] - 1]
就回到了自己的位置,而 num[i]
还要继续判断是否需要交换位置,直到 num[i]
与 num[num[i] - 1]
相等的时候或者 num[i]
的值不在正数范围内的时候停止交换。实现这个过程就是这个题的解法。
代码
class Solution {
public int firstMissingPositive(int[] nums) {
int length = nums.length;
for (int i = 0; i < length; i++) {
while (nums[i] >= 1 && nums[i] <= length) {
if (nums[i] == nums[nums[i] - 1]) break;
int tmp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = tmp;
}
}
int ans = 1;
for (int i = 0; i < length; i++) {
if (nums[i] == i + 1) ans++;
else break;
}
return ans;
}
}