LeetCode-41.缺失的第一个正数

题目

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

示例 1:

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

示例 2:

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

示例 3:

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

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

解题思路—正负翻转:此题有严格的时间复杂度与空间复杂度的要求,想要符合这个要求并不容易,所以该题级别判为困难不是没有原因的!!!解决此题的突破点是要充分利用原来的数组,在原数组上修改。

下面以例子来解释思路:

  • 数组 nums 为 [1,2,-1,-2,0,8,5] ,先从头到尾遍历一遍,判断数组中有没有1的存在。如果存在1,则继续下一步;如果不存在,则输出最小的正整数1。
  • 因为题目中要求的是没有出现的最小的正整数,所以负数和0在数组中没有意义。数组长度为7,而数组最大值为8,代表前面肯定有元素缺失,所以大于数组长度的值也没有意义。现在将数组中所有 负数、0和大于数组长度的数 都置1。
  • 现在nums变为 [1,2,1,1,1,1,5] ,正式开始判断数组中缺少的最小正整数。从头开始遍历,现在数组中有1,2,5,将num[0,1,4]中的数值都变为负数(从0开始),表明当前元素存在。即num为 [-1,-2,1,1,-1,1,5] ,数组中元素一旦变为负数就不再更改(所以重复的数比如1,num[0]只需要变1次。)这种做法不会改变数组原本的数,取值的时候只需要加一个abs就行。
  • 从头遍历修改后的 [-1,-2,1,1,-1,1,5] ,返回第一个为正数的数组索引值+1即可(从0开始),也就是3。
  • 如果遍历完还没有return,就说明当前数组无缺失,返回 nums.length+1 即可。

Java解题—正负翻转

class Solution {
    public int firstMissingPositive(int[] nums) {
        if(nums==null || nums.length==0) return 1;

        // 判断数组中是否有1
        int isone = 0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==1)
                isone++;
        }

        if(isone==0)
            return 1;
        // 把所有 负数和0和超出数组长度的数 都置1
        for(int i=0;i<nums.length;i++){
            if(nums[i]<=0 || nums[i]>nums.length)
                nums[i] = 1;
        }

        for(int i=0;i<nums.length;i++){
            int n = Math.abs(nums[i]);
            if(nums[n-1]>0)
                nums[n-1] = -nums[n-1];
        }

        for(int i=0;i<nums.length;i++){
            if(nums[i]>0)
                return i+1;
        }

        return nums.length+1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值