Leetcode--First Missing Positive

https://oj.leetcode.com/problems/first-missing-positive/数组

感受这题还蛮难的,O(n)的时间,常数大小的额外空间,这个要求仍是比较苛刻的spa

首先,数组应该是能够修改的,不然恐怕无法作了,由于总要有一个地方来记忆一些信息,既然不给O(n)的额外的空间,只能在本地记忆了code

想法是:blog

从左到右扫描数组,把数字放到恰当的位置上(把K放到数组的A[K-1]中,放以前,要把A[K-1]记下来)leetcode

好比A[] = [3,4,-1,1],准备一个额外空间idx,get

扫描到3时,先把A[2]的值记入idx(为3这个数腾出空间),而后把3放到A[2]it

而后就处理存储在idx中的这个值,发现idx<=0,那么不用管io

此时数组变成[3,4,3,1]class

 

而后扫描第二个位置,即A[1]=4循环

将A[3]的值记入idx,而后把4放入A[3]

当前状态:idx=1,A[]=[3,4,3,4]

而后处理存储在idx中的这个值,idx=1,知足idx>0 && idx <= sizeOfArray(对于1到sizeOfArray之间的数字,都是要处理的,由于结果就是这中间的某个数)

把A[0]的值记入idx,把当前的idx记入A[idx-1],即把1记入A[0]

当前状态:idx=3,A[]=[1,4,3,4]

而后又是要处理存储在idx中的这个值,此时idx=3,发现A[2]==3,不须要继续处理了(由于继续下去就是无限循环)

 

而后扫描第三个位置,一样发现A[2]==3,不须要处理

而后扫描第四个位置,发现A[3]==4,不须要处理

注意到咱们在处理的过程当中,没有丢失1到sizeOfArray之间的任何一个数字,因此能够保证结果的正确性

 

而后从左到右第二次扫描这个数组,这个时候,有以下条件成立:对出如今原数组中的1到sizeOfArray之间的任何一个数字K,它确定被放到了A[K-1]

因此扫描的时候,若是遇到A[i]!=i+1,那么说明i+1在原数组中不存在,结果就是i+1

若是A[i]==i+1对i从0到sizeOfArray-1都成立,结果就是sizeOfArray+1

 

//result must be in [1..n]
class Solution {
public:
    int firstMissingPositive(int A[], int n) {
        for(int i = 0; i < n; i++){
            if(A[i] == i+1) continue;
            //a[i]!=i+1
            int idx = A[i];
            while(idx > 0 && idx <= n){
                if(A[idx-1] == idx) break;
                int tmp = A[idx-1];
                A[idx-1] = idx;
                idx = tmp;
            }
        }
        for(int i = 0; i < n; i++){
            if(A[i] != i+1){
                return i+1;
            }
        }
        return n+1;
    }
};
相关文章
相关标签/搜索