LeetCode41-缺失的第一个正数

给定一个未排序的整数数组,找到其中缺失的第一个正整数。例如,输入[1,2,0]时,输出3。算法要求时间复杂度为O(n)且使用常数级别空间。解决方案包括两次遍历数组,首次调整数组使得正整数位于正确位置,第二次遍历找出第一个缺失的正数。" 103846847,5589275,Java SPI框架详解:设计与实现,"['java', 'spi']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

说明:
你的算法的时间复杂度应为O(n),并且只能使用常数级别的空间。

解题思路:
1.暴力法

public int firstMissingPositive(int[] nums) {
        //先排序
        Arrays.sort(nums);
        //missing表示预期的下一个缺失的正数
        int missing = 1,repeat = 0;
        for(int i = 0;i < nums.length;i++){
            //小于0的元素不考虑&&!!!与上个正数重复的元素也不考虑
            if(nums[i] <= 0 || nums[i] == missing - 1){
                continue;
            }
            //如果nums[i]>0且等于下一个预期的正数
            if(nums[i] == missing){
                //更新repeat和missing
                repeat = missing;
                //说明不缺失当前正数,预期的下一个缺失正数是missing+1
                missing++;
                continue;
            }else{
                //如果nums[i]>0且不等于下一个预期的正数,那么就相当于缺失这个正数
                return missing;
            }

        }
        return missing;
    }

在这里插入图片描述

2.两次循环遍历,第一次顺序扫描,判断当前数nums[i],若当前数处在0-n-1范围内,且nums[i] != i + 1则寻找与当前数应在位置现在的数nums[nums[i] - 1],若不相等则交换,(易错的是,交换后的这个位置上的新的数还需要接着判断),若相等则break直接扫描下一个数。如此重复下去。第二次顺序遍历的过程中,若发现第一个nums[i] != (i + 1),则返回i + 1即为第一个缺失的正数;否则遍历完都没出现那么答案,返回n + 1即可。

java代码如下:

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        int cur,temp;
        //第一次遍历,不断交换
        for (int i = 0; i < n; i++) {
           // cur = nums[i];
            //while条件:当前数必须处在0-n-1范围内,才对之处理。
            while ((nums[i] != i + 1) && (nums[i] > 0) && (nums[i] <= n)){
                if(nums[nums[i] - 1] != nums[i]) {    //防止{1,1}的情况出现
                    temp = nums[nums[i] - 1];
                    nums[nums[i] - 1] = nums[i];
                    nums[i] = temp;
                }else {
                    break;     //当前判断数应该在的位置已经存在该数,则退出直接判断下一个数
                }
            }
        }
        //第二次遍历:找第一个缺失的正数。
        for (int i = 0; i < n; i++) {
            if(nums[i] != (i + 1)){
                return i + 1;
            }
        }
        return n + 1;           //如果每个数都已在它应该在的位置上{1,2,3,4,5},就输出下一个正数6。

    }
//    public static void main(String[] args){
//        //int[] arr = {1,1};
            //int[] arr = {3,4,-1,1};
            //int[] arr = {7,8,9,11,12};
//        System.out.println(new Solution().firstMissingPositive(arr));
//    }
}

运行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值