题目链接
题目分析
这个题如果没有下面的要求的话简直就是白给,直接一个map扫一次数组或者排序就行。
但是它这个既然提到了,我们还是得按照别人的要求做。
我们在剑指Offer里面有一题的思想和这里差不多,就是将满足要求的数放置到对应的下标上,由于题目是正整数,我们的数值应该从1开始,到哪里结束呢?这是个好问题。
我一开始也想用这个思想来做,但是考虑到会有大于数组长度的情况的存在,所以放弃了,结果看了评论区第一居然也是直接一个萝卜一个坑,但是他是舍弃了大于数组长度的那些数。
后来想一想,如果一个数已经比这个数组长度还要大了,说明数组如果就算全部放正整数,那么它前面肯定会有缺失的正整数,真的是妙啊!
我们置换完之后,再进行一次遍历,如果遇到nums[i] != i+1的情况,就表示已经找到了第一个缺失的正整数~
代码实现
class Solution {
public int firstMissingPositive(int[] nums) {
//第一次循环,我们将大小在大于等于1并且小于nums.length的数放入到nums[temp-1]的地方中,其实就是利用了一个萝卜一个坑的思想。
//跟有一道剑指offer的题很像,但是这个题我没想到可以直接忽略掉大于数组长度的数- -
for(int i = 0; i < nums.length; i++){
// 内层循环,注意后面的条件,因为是最小正整数,所以我们的数值是从1开始的,也就代表我们的数是进行了+1的偏移。
while(nums[i] >= 1 && nums[i] < nums.length && nums[i] != i+1){
int temp = nums[i];
//避免无限重复循环,如果交换位置已经有合适的数据了,直接就退出即可。
if(nums[temp - 1] == temp){
break;
}
//交换数据
nums[i] = nums[temp - 1];
nums[temp-1] = temp;
}
}
int i = 0;
//第二轮循环用于寻找缺失的数。
for(; i < nums.length; i++){
if(nums[i] != i+1){
break;
}
}
return i + 1;
}
}
总结
这个题我一年前做过,一开始的做法就是用hash做。然后应该也是受到了评论区的影响提交了第二版的正确答案。但是一年多过去了,居然没想起来怎么做TvT。
话说昨晚太晚睡了,今天中午睡得迷迷糊糊的,看来晚睡对身体真的不好。