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​​