LeetCode 41. 缺失的第一个正数

题目链接

41. 缺失的第一个正数

题目分析

这个题如果没有下面的要求的话简直就是白给,直接一个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。
话说昨晚太晚睡了,今天中午睡得迷迷糊糊的,看来晚睡对身体真的不好。

原文地址:https://www.cnblogs.com/ZJPaang/p/13198963.html