缺失的第一个正数 |刷题打卡

343 阅读2分钟

掘金团队号上线,助你 Offer 临门! 点击 查看大厂春招职位

一、题目描述:

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

进阶:你可以实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案吗?

示例 1:

输入:nums = [1,2,0]
输出:3

示例 2:

输入:nums = [3,4,-1,1]
输出:2

示例 3:

输入:nums = [7,8,9,11,12]
输出:1

题目地址:leetcode-cn.com/problems/fi…

二、思路分析:

首先的思路是先进行排序,然后再进行查找,时间复杂度的瓶颈就在排序上。如果要达到 O(n)的时间复杂度的话,能选择的排序算法貌似也就只有桶排序了。

数组的下标是有序的,可以利用数组的下标。

我们排序的最终目标是: nums[i] = i-1

然后遍历整个数组,如果不符合上述目标的位置是 x,没有出现的最小整数即是 x+1。

下面简单说一下怎么对数组进行排序,如果还是不太明白,可以先学习下如何实现对0-9进行桶排序

先把 nums[0]位置的数拿出来 放到temp里,然后看一下temp 应该放到哪个位置(内循环)。

然后把这个位置的数与temp交换一下,然后再看一下temp应该放到哪个位置。

直到所有的temp没有地方放了,temp的值已经超数组下标了。就结束循环。

然后再去拿nums[1]。

三、AC 代码:

    public int firstMissingPositive(int[] nums) {
        if (nums.length == 0) {
            return 1;
        }

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] - 1 < 0 || nums[i] - 1 > nums.length - 1) {
                continue;
            }
            while (nums[i] - 1 >= 0 && nums[i] - 1 < nums.length && nums[i] - 1 != i) {
                if (nums[nums[i] - 1] == nums[i]) {
                    break;
                }
                int temp = nums[nums[i] - 1];
                nums[nums[i] - 1] = nums[i];
                nums[i] = temp;
            }
        }
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] - 1 != i) {
                return i + 1;
            }
        }
        return nums.length + 1;
    }

四、总结:

需要注意数组下标越界的问题。