第一個缺失的最小正數(優化)
阿新 • • 發佈:2018-12-12
題目中提到線性時間和常數級的空間限制。
方法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;
}