1. 解题原理:
(1)对于一个有序的、不缺失元素的正数数组nums,元素nums[i]应当位于nums[i]-1的位置处。
(2)nums数组的长度为N,缺失的第一个正数如果不位于[1,N],那么就肯定是N+1
2. 解题步骤
(1)元素替换:负数和0对“有序的、不缺元素的、正数”数组没影响,所以把负数元素、0元素都替换成N+1,现在数组nums中只有两部分了:[1,N]的部分(这部分可能存在也可能不存在)、大于等于N+1的部分。
(2)位置标记:对于一个正数元素nums[i],它在有序的、不缺失元素的正数数组nums中的位置应当是nums[i]-1,所以我们将元素nums[nums[i]-1]取相反数,用来表示该位置的元素是存在的。
因为nums[nums[i]-1]取过相反数后会变成负数,所以在判断其对应位置的元素是否存时,我们需要进行取绝对值操作。
(3)寻找第一个正数:遍历下标index,哪个下标对应的元素还是正数,就说明值为“这个下标+1”的正数缺失了
3. 代码
int n = nums.length;
// 非正数都变成n+1,再也不管它们了
for(int i=0; i<n; ++i){
if(nums[i] <= 0){
nums[i] = n+1;
}
}
// 标记数组中存在的元素
for(int i=0; i<n; ++i){
// 取绝对值是因为 num-1位置在置负数的过程中,可能已经将正数变为负数了
int num = Math.abs(nums[i]);
if( num <= n ){
nums[num-1] = -1* Math.abs(nums[num-1]);
}
}
// 找到缺失的最小正数——遍历过程中遇到的第一个正数
for(int i=0; i<n; ++i){
if(nums[i]>0){
return i+1;
}
}
return n+1;