【困难】41. 缺失的第一个正数

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

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

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

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

示例3:输入:nums = [7,8,9,11,12];输出:1

提示:0 <= nums.length <= 300;-231 <= nums[i] <= 231 - 1

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/first-missing-positive

**我的思路**

/* 说明:从 1开始依次枚举正整数,并遍历数组,判断其是否在数组中。但是递归函数的空间复杂度比较复杂,与递归算法所生成的最大递归树的深度成正比。如果不用递归的话则空间复杂度是o(1),时间复杂度是o(n*2)。*/

class Solution {

    public int firstMissingPositive(int[] nums) {

        int min = 1;//min记录当前最小未出现的正整数

        return compareN(min,nums);

    }

    public int compareN(int min,int[] nums){

        int minn = min;

        for(int i = 0; i < nums.length; i++){

            if(minn == nums[i]){//说明当前的min已经在数组中出现

                ++minn;

                return compareN(minn,nums);//新的min与数组遍历比较看是否有出现

            }    

        }

        return minn;//直到数组遍历完,返回未出现的min值

    }

}

**借鉴思路1—哈希表**

作者:liweiwei1419

链接:https://leetcode-cn.com/problems/first-missing-positive/solution/tong-pai-xu-python-dai-ma-by-liweiwei1419/

来源:力扣(LeetCode)

/* 说明:先将所有数组中的数放入哈希表中,再从1开始依次枚举正整数,判断是否在哈希表中。时间复杂度是o(n),空间复杂度是o(n)。*

import java.util.HashSet;

import java.util.Set; 

public class Solution { public int firstMissingPositive(int[] nums) { int len = nums.length; Set<Integer> hashSet = new HashSet<>(); for (int num : nums) { hashSet.add(num);//将数组中的值加入到哈希表中 } for (int i = 1; i <= len ; i++) { if (!hashSet.contains(i)){//如果哈希表中不包含i,则i是当前的最小正整数 return i; } } return len + 1;//如果1~len的值哈希表都包括了,则返回len+1是最小没出现的正整数 } }

**借鉴思路2—原地哈希(将数组看成哈希表)**

作者:liweiwei1419

链接:https://leetcode-cn.com/problems/first-missing-positive/solution/tong-pai-xu-python-dai-ma-by-liweiwei1419/

来源:力扣(LeetCode)

/* 说明:哈希表是一个可以支持快速查找的数据结构:给定一个元素,我们可以在 o(1)的时间内查找元素是否在哈希表中。但是将n个数存在哈希表中使用了n个空间,空间复杂度不符合要求,所以我们可以将数组设计成哈希表的思路。也就是①我们已经知道最小的正整数一定在1~n+1之间(数组中如果1~n都找到了,则返回n+1),我们利用数值为 i 的数映射到下标为i- 1的位置(遍历数组,将数值1放在下标0的位置,数值2放在下标1的位置。遍历完后再遍历一遍数组,当遇到数值不等于数值下标+1的时候说明是我们缺少的最小正整数。)。此时满足时间复杂度o(n),空间复杂度o(1)*/

public class Solution {

    public int firstMissingPositive(int[] nums) {

        int len = nums.length;

        for (int i = 0; i < len; i++) {

            while (nums[i] > 0 && nums[i] <= len && nums[nums[i] - 1] != nums[i]) {//满足下标不越界1~n并且没有放在正确的位置上,才交换

                swap(nums, nums[i] - 1, i);//数值nums[i](下标i)要和下标为nums[i]-1的数值交换

            }

        }

        for (int i = 0; i < len; i++) {

            if (nums[i] != i + 1) {//数组交换完成后再遍历数组,如果数值不等于下标+1说明返回下标+1是缺失最小正整数

                return i + 1;

            }

        }

        return len + 1;//如果数值和下标映射成功,则缺失最小正整数是len+1,例如[1,2,3] 返回4

    }

    private void swap(int[] nums, int index1, int index2) {

        int temp = nums[index1];

        nums[index1] = nums[index2];

        nums[index2] = temp;

    }

}

 

posted @ 2021-02-22 23:01  84周一X  阅读(45)  评论(0)    收藏  举报