zoukankan      html  css  js  c++  java
  • 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 这两个条件其实可以整合在一起。以后刷第三遍的时候再改吧。

  • 相关阅读:
    CodeForces-1263D Secret Passwords 并查集 求连通分量
    Virtual Friends HDU
    AreYouBusy HDU
    Jack Straws POJ
    Divisibility by 25 CodeForces
    逃离迷宫 HDU
    Find a way HDU
    Stall Reservations POJ
    Three displays CodeForces
    Radar Installation POJ
  • 原文地址:https://www.cnblogs.com/boring09/p/4245977.html
Copyright © 2011-2022 走看看