41. 缺失的第一个正数
思路
分析题目
题目直接告诉了空间复杂度O(1),那只能是原地置换了
没有出现的最小的,那么想到的就应该是有序数组
步骤
那就还是老样子,咱们自己先定一个规则
-
数组下标就是元素的值。例:
array[0] = 0
,array[1] = 1
…以此类推
但是 题目要的是正整数,那0就没必要存了,那就是array[0] = 1
,array[1] = 2
-
经过这样移动一番,再遍历找哪个下标和元素不对应,就直接返回下标+1
细节
这样分析下来,题目步骤明确了,可是细节还有很多
-
让数字n回到下标n-1的位置;目的是保证数组内的所有数字都大于0(题目要求返回正整数)
-
数字找家的时候,不是所有数字都有家:正数才有家
-
为避免索引越界异常,数字不能大于数组长度
-
为避免交换时死循环,相同的数字不能存入
-
如果所有数都在对应的位置,那就返回数组长度+1
如果思考起来有点乱 就举例,比如数字1应该在索引0的位置,数字2在索引1的位置
代码(附详细注释)
class Solution {
public int firstMissingPositive(int[] nums) {
if (nums.length == 0){
return 1;
}
//让每个数字n都回到下标为n-1的家里;例:数字2回到下标1的位置
for (int i = 0; i < nums.length; i++) {
//情况考虑周全:正数才能存;数字不能大于长度(否则索引越界异常);防止交换的两个数相等进入死循环
while (nums[i] > 0 && nums[i] <= nums.length && nums[i] != nums[nums[i] - 1]){
//下标(元素-1的数 才是应该去的索引)
int index = nums[i] - 1;
//交换
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
}
}
//遍历
for (int i = 0; i < nums.length; i++) {
//例:数字1 不在索引为0的位置上
if (nums[i] != i+1){
return i+1;
}
}
//数组填满,则返回长度+1的值
return nums.length+1;
}
}