1. 程式人生 > >第一個缺失的最小正數(優化)

第一個缺失的最小正數(優化)

題目中提到線性時間和常數級的空間限制。

方法1中迴圈中雖然出現迴圈,但是時間複雜度仍然是線性級別的,且空間複雜度為常數級別;

方法2中採用遞迴思想。雖然時間複雜度滿足,但是空間複雜度隨著遞迴深入成與陣列長度線性相關;

方法3和方法1類似,只是方法3採用每次遇到小於陣列長度n的正整數,就進行調換位置,方法1則用一個臨時變數來儲存。

方法4是通過將正數都放後面,從第一個正數開始,將存在小於n,對應位置置為負數。也是用到雜湊原理。

方法1-4都是以陣列本身作為雜湊表。

方法5雖然空間複雜度為0,但是時間複雜度可能為O(n2),比如最壞情況陣列元素為{1,2,3,4,5,5,6,.....,n};

方法1:

int firstMissingPositive(int A[], int n)
{
    int index=0,i=0,temp=0;
    while(i < n)
    {
        index=A[i]-1;
        if(A[i]>0 &&A[i]<=n &&A[i]!= A[index]){
            if((A[index] <=0 ||A[index]> n))
                A[index]=index+1;
            else  {
                do {
                    temp=A[index];
                    A[index]=index+1;
                    index=temp-1;
                } while(index+1!=A[index]&&A[index]>0&&A[index]<=n);
                if(A[index]<=0||A[index]>n)A[index]=index+1;
            }
        }
        i++;
    }
    for(i = 0; i < n; i++)
        if(A[i]!=i+1) break;
    return i+1;
}

方法2:

void move(int *nums,int index,int pNums){
    int temp=nums[index];
    if(temp>pNums||temp==nums[temp-1])return;
    nums[index]=0;
    if(nums[temp-1]>0)move(nums,temp-1,pNums);        
    nums[temp-1]=temp;   
}
int firstMissingPositive(int* nums, int numsSize) {
    int i=0,count=0;
    for(i=0;i<numsSize;i++)
        if(nums[i]>0)count++;
    for(i=0;i<numsSize;i++){
        if(nums[i]<=0||nums[i]>count)continue;
        move(nums,i,count);
    }
    for(i=0;i<count;i++)
        if(nums[i]!=i+1) break;
    return i+1;
}

方法3:

int firstMissingPositive(int A[], int n)
{
    int index=0,i=0;
    while(i < n)
    {
        if(A[i]<=0 ||A[i]>n || A[i]== A[A[i]-1]){ i++;continue; }
        index=A[i]-1;
        if(A[index] <=0 ||A[index]> n){
            A[index]=index+1;
            i++;
        }
        else
        {
            A[i] = A[index];
            A[index] = index+1;
        }
    }
    for(i = 0; i < n; i++)
        if(A[i]!=i+1) break;
    return i+1;
}

再看看別人寫的

方法4:

int sagrigate(int *a,int n)
{
    int j=0;
    int temp=0;
    for(int i =0 ;i<n;i++)
    {
        if(a[i]<=0)
        {
           temp=a[j];
            a[j]=a[i];
            a[i]=temp;
            j++;
        }
    }
    return j;
}

int  miss(int *a,int n)
{
    for(int i=0;i<n;i++)
    {
        if( abs(a[i])-1<n && a[abs(a[i])-1]>0)
        {
            a[abs(a[i])-1]=-a[abs(a[i])-1];
        }
        
    }
    for(int i=0;i<n;i++)
    {
        if(a[i]>0)
            return i+1;
    }
    
     return n+1;
}

int firstMissingPositive(int* nums, int n) {
    int k;
    k= sagrigate(nums,n);
    return  miss(nums+k,n-k);
}

方法5:

int firstMissingPositive(int* nums, int numsSize) {
    int t = 1;
    int i;
    for(i = 0; i < numsSize;)
    {
        if(nums[i] > 0 && nums[i] == t)
        {
            t++;
            i = 0;
            continue;
        }
        else
            i++;
    }
    return t;
}