First Missing Positive

题目:

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.

开始理解题目的点问题,以为是漏掉的一个数,其实应该是第一个漏掉的自然数,这里自然数当然不包括0。所以只要从1开始每次加一看哪一个数没有出现在列表中就得到结果了,关键是怎么依次查呢?当时没想到办法,后来有人说是hash。这貌似可以,但空间不是常数空间,需要一个空间把数都映射进去,接着突然想到把当前元素的位置与它的值对应的位置作交换,比如[3,4,-1,1]中,元素3放到第三个位置上去得到[-1,4,3,1],接着再往下交换,如果当前位置的值小于1或者大于长度n都抛弃,直接扫描下一个元素。最后再从列表头开始扫描,直到漏网之鱼的出现。比如上面的例子最后得到[1,-1,3,4]这样扫描发现1后面不是2所以结果就是2。代码如下:

 1     int firstMissingPositive(int A[], int n) {
 2         for(int i=0;i<n;i++){
 3             while(A[i]>0&&A[i]<=n&&A[i]!=i+1&&A[A[i]-1]!=A[i]){
 4                swap_v(&A[A[i]-1],&A[i]);
 5             }
 6         }
 7         int j;
 8         for(j=0;j<n&&A[j]==j+1;j++){}
 9         return j+1;
10     }
11     void swap_v(int *a,int* b){
12         int t = *a;
13         *a = *b;
14         *b = t;
15     }

其中要注意一下当前的元素是否和要交换位置的元素是相同的值,或者本身就是已经在自己的位置上。写完代码后看一下时间复杂度是多大?看到两个嵌套循环时误以为是O(n2)可能要过不了大集合了,结果12ms全pass了,其实仔细一想,第一个元素经过一次交换都能到达自己最终的位置上,对于长度为n的列表,至多n次交换就可以得到元素的最终位置结果,时间复杂度是O(n)啦。

posted @ 2013-12-12 18:37  月窟仙人  阅读(174)  评论(0编辑  收藏  举报