1、41. 缺失的第一個正數
給定一個未排序的整數數組,找出其中沒有出現的最小的正整數。
示例 1:
輸入: [1,2,0] 輸出: 3
示例 2:
輸入: [3,4,-1,1] 輸出: 2
示例 3:
輸入: [7,8,9,11,12] 輸出: 1
思路:交換數組元素。使得數組中第i位存放數值(i+1)。
最后遍歷數組,尋找第一個不符合此要求的元素,返回其下標。整個過程須要遍歷兩次數組,復雜度為O(n)。
下圖以題目中給出的第二個樣例為例,解說操作過程。
class Solution { public: int firstMissingPositive(vector<int>& nums) { if(nums.empty()) return 1; int n = nums.size(); for(int i=0;i<n;++i) { if(nums[i] <= 0) continue; //思路:交換數組元素。使得數組中第i位存放數值(i+1)。 //假設交換的數據還是大於0且<i+1,且數據不相等,則放在合適的位置,避免死循環 while(nums[i]>0 && nums[i]<=i+1 && nums[i] != nums[nums[i]-1]) swap(nums[i], nums[nums[i]-1]); } for(int i=0;i<n;++i) { if(nums[i] != i+1) return (i+1); } return n+1; } };
2、268. 缺失數字
給定一個包含 0, 1, 2, ..., n
中 n 個數的序列,找出 0 .. n 中沒有出現在序列中的那個數。
示例 1:
輸入: [3,0,1] 輸出: 2
示例 2:
輸入: [9,6,4,2,3,5,7,0,1] 輸出: 8
這道題還可以用二分查找法來做,我們首先要對數組排序,然后我們用二分查找法算出中間元素的下標,然后用元素值和下標值之間做對比,如果元素值大於下標值,則說明缺失的數字在左邊,此時將right賦為mid,反之則將left賦為mid+1。那么看到這里,作為讀者的你可能會提出,排序的時間復雜度都不止O(n),何必要多此一舉用二分查找,還不如用上面兩種方法呢。對,你說的沒錯,但是在面試的時候,有可能人家給你的數組就是排好序的,那么此時用二分查找法肯定要優於上面兩種方法。
class Solution { public: int missingNumber(vector<int>& nums) { if(nums.empty()) return -1; int n = nums.size(); sort(nums.begin(),nums.end()); int left = 0,right = n; while(left<right) { int mid = (left+right)/2; if(nums[mid] == mid) left = mid+1; else right = mid; } return right; } };