本题题目要求如下:
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,一般到hard这个难度,题目要求越直接,解法就越逆天。。。果不其然,我没有想到解法,而且看谈论区出现的解法也有些过于复杂,即便看答案做出来也没啥意义,因为具有不可复制性,除非考到原题,不然基本没用。。。我从一个人的博客看到了他的思路觉得特别好,就用他的方法解了这道题,虽然未必比那个leetcode排名第一的解更加高效,但至少我认为这么解决问题可以给我一点启发,以后看别的类似问题,会多一种思路。。这道题其实一般人最直观的解法肯定是用hashmap,但是这道题有了限定条件space complexity is O(1),所以就貌似没法用,但是其实还是可以用,只不过要充分利用该数组。
我们拿第二个input举例子,说明我的处理方法。。
[3,4,-1,1]我们把第三个元素设为5,即一个大于n的元素,就变成[3,4,5,1]这里面所有元素都大于零,
A[0] = 3自然指的是A数组第一个元素为3,但是我们可以再给其另外一层含义,即hash[1] = true/false;
因为我们有1,即A[3] = 1,所以在此时,将A[0]置于-3,这个'-'就代表hash[1] = true,反之,就是true。
简单说先过程
++++++++++++++++++++++++++++++++++++++++++
第一次遍历:
3,4,5,1
第二次遍历:
3,4,-5,1此时说明hash[3]存在
3,4,-5,-1 此时说明hash[4]也存在
(在遍历时,用绝对值)
-5跳过,因为其绝对值大于n
-3,4,-5,-1此时说明hash[1]也存在,
这样开始第三次遍历:
第一个非负是4,A[1],其在hashmap中表示hash[2]不存在
即2不存在
++++++++++++++++++++++++++++++++++++++++++
我的描述可能不太好,如果还不明白,就直接看代码吧:
class Solution {
public:
int firstMissingPositive(int A[], int n) {
/* first iteration: change all the value out of bound to (n + 1) */
const int out_of_bound = n + 1;
for (int i = 0; i < n; ++i)
if (A[i] <= 0)
A[i] = out_of_bound;
/* second iteration: construct a hash map. map<int, int>, first argument is index
* second argument: if positive, it exist, else, it doesn't. e.g. A[0] = 4,
* A[0] (i.e. 1) exist */
for (int i = 0; i < n; ++i) {
int abs_i = abs(A[i]);
if (abs_i <= n)
A[abs_i-1] = -abs(A[abs_i-1]);
}
/* third iteration: check the first positive value in A[] */
for (int i = 0; i < n; ++i) {
if (A[i] > 0)
return i + 1;
}
return n + 1;
}
};