[LeetCode]First Missing Positive

本文介绍了一种在未排序整数数组中查找首个缺失正整数的方法,提出了两种算法:DP算法和HashMap算法,这两种算法均能在O(n)时间内运行,并占用常数空间。

Question
Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.


本题难度Hard。有2种算法分别是: DP和HashMap(推荐)

1、DP

【复杂度】
时间 O(N) 空间 O(N)

【思路】
我们只要将最小的一段连续值(记住是连续的值)的范围(min,max)求出,然后:

if min>1 
    ans=1
else 
    ans=max+1

主要问题在于数字是乱序的,所以就使用DP。对于nums[i]无非就是几种情况:
1、min>nums[i]
如果min-1==nums[i],那么min移到nums[i]
否则,就是出现了新的最小的(min,max)(与当前的(min,max)断开了),那么就保存当前的(min,max),再跳到新的(min,max)

2、max<nums[i]
如果max+1==nums[i],这里不是立即就将max移到nums[i],因为有可能这里的nums[i]之前已经判断过了,所以要到map中查看之前有没有保存过;然后还要判断max+1以及以后的有没有保存过(行32-34)
否则,这里我们就不必再移动(min,max),如果nums[i]没有保存过,就进行保存

【注意】
1、在对min和max进行初始化时候,是从nums中找到正数(行14-20)
2、同理,在处理过程中,我们只对正数进行处理(行22)

【代码】

public class Solution {
    public int firstMissingPositive(int[] nums) {
         //require
         if(nums==null)
            return 1;
        int size=nums.length;
        if(size<1)
            return 1;

        int ans=-1;
        //invariant
        Map<Integer,Integer> map=new HashMap<Integer,Integer>();
        int max=0,min=0,index=0;
        for(int i=0;i<size;i++){
            if(nums[i]>0){
                max=nums[i];min=nums[i];
                index=i;
                break;
            }
        }
        for(int i=index+1;i<size;i++){
            if(nums[i]>0){
                if(min>nums[i]){
                    if(min-1==nums[i]){
                        min=nums[i];
                    }else{
                        map.put(min,max);//dp
                        min=nums[i];max=nums[i];
                    }
                }else if(max<nums[i]){
                    if(max+1==nums[i]){
                        max=(map.containsKey(nums[i]))?map.get(nums[i]):nums[i];//dp
                        while(map.containsKey(max+1)){
                            max=map.get(max+1);
                        }
                    }else{
                        if(!map.containsKey(nums[i]))
                            map.put(nums[i],nums[i]);

                    }
                }
            }
        }
        if(min<2)
            ans=max+1;
        else
            ans=1;
        //ensure
        return ans;
    }
}

2、HashMap

【复杂度】
时间 O(N) 空间 O(N)

【思路】
将所有正数都先放到map里面,然后就从小正数——也就是1——开始检查map,遇到的第一个不包含在map中的正数便是答案。(简直就是暴力的美学)

【代码】

public class Solution {
    public int firstMissingPositive(int[] A) {
        HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>();
        for (int a : A) {
            if (a > 0) {
                map.put(a, true);
            }
        }
        int v = 1;
        while (true) {
            if (!map.containsKey(v)) {
                break;
            }
            v++;
        }
        return v;
    }
}

参考

First Missing Positive@LeetCode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值