Leetcode#41 First Missing Positive

原题地址

 

非常有技巧的一道题,如果没有接触过类似题目或没有任何提示的情况下想出来很困难,因为题目要求O(1)的空间复杂度

既然是O(1)的空间复杂度,自然要用到原数组了。

解法是:

1. 遍历每个数组元素,把元素都交换到正确的位置上。比如发现A[3] = 5,则交换A[5]和A[3],让A[5]=5。

2. 再遍历一次,遇到第一个A[i] != i就是所求解

当然,交换过程是个迭代过程,有可能交换一次之后发现还可以交换,则继续交换下去,直到没法交换了。

什么情况下停止交换?

1. 遇到0或负数。这种数字没有对应的位置

2. 遇到比n大的数字。

 

有一个小技巧:如果发现当前位置的数字过大(即对于任意位置i有A[i] > i),则不需要交换,因为迟早会把A[i]交换到正确的位置上的。

比如A[3]=5,假如3存在,则后面肯定会遇到某个位置k且A[k]=3,此时会将A[3]和A[k]交换,交换后A[k]=5。

如果k<5,交换A[k]和A[5],结果是A[5]=5

如果k>5,又回到了一开始的情况,停止交换

利用这个技巧可以简化代码,但是不会提高效率。

 

代码:

 1 int firstMissingPositive(int A[], int n) {
 2   for (int i = 0; i < n; i++)
 3     while (A[i] <= i && A[i] > 0 && A[i] != A[A[i] - 1])
 4       swap(A[i], A[A[i] - 1]);
 5 
 6   for (int i = 0; i < n; i++)
 7     if (A[i] != i + 1)
 8       return i + 1;
 9   return n + 1;
10 }

 

PS: 上述代码还不完美,A[i] != A[A[i] - 1] 和 A[i] <= i 这两个条件其实可以整合在一起。以后刷第三遍的时候再改吧。

posted @ 2015-01-24 15:36  李舜阳  阅读(159)  评论(0编辑  收藏  举报