缺失的第一个正数

问题描述

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。原题链接
数据范围:
1 <= nums.length <= 5 * 105
-231 <= nums[i] <= 231 - 1

思路与方法

初见此题首先想到的是哈希,用一个和nums数组长度相同的布尔数组来表示数字1到n(n为nums数组长度)是否出现,出现了则将对应位置标为true,然后遍历布尔数组,第一个为false的位置对应数就是答案。但题目要求空间复杂度为O(1),故尝试在原数组上进行哈希,由于期望标记的数范围是1到n,所以不在此范围的数可以修改为任意大于n的正数,然后就可以通过给负号来标记出现的正数,但同时又可以通过绝对值来知道它原本的值,最后遍历数组,第一个不为负的下标对应的数为答案。
完整流程如下:
1.第一遍遍历数组,将所有不在1到n范围内的数修改为n+1;
2.第二遍遍历数组,若当前数绝对值在1到n范围内,则将以该绝对值-1为下标的正数取负(若已为负数则不再取负);
3.第三遍遍历数组,第一个为正的数下表+1即是没有出现过的最小正数。

Code

public int firstMissingPositive(int[] nums) {
           int n=nums.length;
           for(int i=0;i<n;i++){
               if(nums[i]<1||nums[i]>n)nums[i]=n+1;
           }
           for(int i=0;i<n;i++){
               int tmp=Math.abs(nums[i]);
               if(tmp>=1&&tmp<=n&&nums[tmp-1]>0)//若为正,取负
               nums[tmp-1]=-nums[tmp-1];
           }
           for(int i=0;i<n;i++){
               if(nums[i]>0)return i+1;
           }
           return n+1;
    }

复杂度分析

三次遍历原数组,每一次都是O(n)的时间,所以总的时间复杂度还是O(n),内存上是在原数组上作修改,只用了常数量级的空间,空间复杂度为O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值