演算法練習week10--leetcode41
阿新 • • 發佈:2018-11-19
題目:
給一無序陣列,找到陣列中從1開始第一個不出現的正整數。
要求O(n)的時間複雜度和常數空間複雜度。
思路:
1、方法一:
先排序,然後遍歷陣列,找出第一個不出現的正整數。但時間複雜度為O(nlogn),不符合要求。
實現如下:
#include <iostream> #include <algorithm> using namespace std; int firstMissPositive(int A[],int n){ sort(A,A+n,less<int>()); int i=0; while(A[i]<=0) i++; int j=1; while(i<n){ if(i<n-1 && A[i]==A[i+1]) i++; if(A[i]!=j) break; i++; j++; } return j; } int main() { int A[]={4,4,3,-1,-2,2,1}; int n=sizeof(A)/sizeof(A[0]); cout<<firstMissPositive(A,n); return 0; }
2、方法二:
對於正整數A[i],如果將它放在陣列中滿足A[i]=i+1的位置,那麼如果當某個位置不滿足A[i]==i+1時,則i為第一個不出現的正整數。
- 遍歷陣列,
- 當遇到小於n(n為陣列大小)的正整數,如果它滿足A[i]=i+1,則跳過,i++,如果不滿足則將它交換它屬於它的位置,即swap(A[i],A[A[i]-1]);
- 當遇到小於0或者大於n的數,或者需交換的位置已經有了滿足條件的值即A[i]==A[A[i]-1](陣列中有重複數字的時候會有這種情況),則跳過,i++,因為沒有合適的位置可以跟它們交換。
- 再次遍歷陣列,如果A[i]!=i+1,則i為第一個不出現的正整數。
程式碼如下:
class Solution { public: void swap(int &a,int &b){ int tmp; tmp=a; a=b; b=tmp; } int firstMissingPositive(vector<int>& nums) { int n=nums.size(); // if(n==0) return 1; int i=0; while(i<n){ if(nums[i]==i+1 || nums[i]==nums[nums[i]-1] || nums[i]<=0 || nums[i]>n) i++; else swap(nums[i],nums[nums[i]-1]); } for(i=0;i<n;i++){ if(nums[i]!=i+1) break; } return i+1; } };