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 constantspace.
思路:寻找数组中“丢失”的第一个正整数,意思就是,如果对于正整数序列1,2,3,…,查看该数组缺失的第一个正整数。要求时间复杂度为O(n),空间复杂度为O(1)。
如果没有时间复杂度和空间复杂度的限制,解决该题,第一个想到的就是排序,排序后就可在O(n)的时间内找到缺失的第一个整数。但是一般的排序算法最快也是O(nlogn)的。
算法导论中介绍了时间复杂度为O(n)的排序算法,这种排序算法必须满足一定的条件,比如数据的范围固定在一个较小区间内,即可按照数据本身的值进行排序(哈希)。
本题其实也符合这种条件,对于长度为size的数组,则其最多能包含的完整序列也就是1,2,…,size。对于数组中大于size的整数,以及小于1的整数,完全不用关心,只需要关心1,2,…,size范围内的整数。将该范围内的整数,按照他们的值放在相应的位置上,将该范围之外的值直接置为0。然后从前往后扫描一遍数组,第一个值为0的数组元素的索引,即是结果。
该过程中要注意重复数据的问题。代码如下:
int firstMissingPositive(int* nums, int numsSize) { int i, tmp; for(i = 0; i < numsSize; i++) { tmp = nums[i]; while(tmp != i+1) { if(tmp > numsSize || tmp < 1 || tmp == nums[tmp-1]) { nums[i] = 0; break; } nums[i] = nums[tmp-1]; nums[tmp-1] = tmp; tmp = nums[i]; } } for(i = 0; i < numsSize; i++) { if(nums[i] == 0) return i+1; } return numsSize+1; }