劍指 Offer 53 - II. 0~n-1中缺失的數字(C++)
阿新 • • 發佈:2020-07-29
目錄
題目
一個長度為n-1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0~n-1之內。在範圍0~n-1內的n個數字中有且只有一個數字不在該陣列中,請找出這個數字。
示例1:
輸入: [0,1,3]
輸出: 2
示例2:
輸入: [0,1,2,3,4,5,6,7,9]
輸出: 8
限制:
1 <= 陣列長度 <= 10000
分析與題解
題解一
假設 0~n-1 中沒有數字 i ,那麼這 n - 1 個數字的和為 sum = n(n-1)/2 - i,那麼 i = n(n-1)/2 - sum。
程式碼如下:
class Solution { public: int missingNumber(vector<int>& nums) { int size = nums.size(); int sum=0; for(int i=0;i<size;i++) { sum+=nums[i]; } int total = (1+size)*(size)/2; return (total-sum); } };
題解二
因為要不重複地將0~n-1填入到n-1個空位中,所以首個下標與陣列元素不等的位置,缺失的數值與當前下標相等。如果遍歷陣列後,所有下標都與其對應的陣列元素相等,那麼缺失的元素即為n-1。程式碼如下:
class Solution { public: int missingNumber(vector<int>& nums) { int size = nums.size(); for(int i=0;i<size;i++) { if(nums[i]!=i) return i; } return size; } };
題解三
上述倆題解的時間複雜度均為 O(n)。與題解二類似,同樣依賴於整個陣列元素按照遞增序列進行排序的。如果任意下標i與其對應陣列元素相等,那麼缺失的元素一定在i+1到n-1之間;如果不等,則缺失的數字在0~i之間。因此採用二分查詢法思想去優化時間複雜度。
若i==nums[i],則下標i左邊只有0~i-1可以使用,並且空位總數為i,又需要按照遞增排序,所以位置確定無二義性
程式碼如下:
class Solution { public: int missingNumber(vector<int>& nums) { int mid=0,left=0; int right=nums.size(); while(left<right) { mid = (left+right)/2; if(nums[mid]==mid) //不確定是否為第一個下標不等的元素 { left = mid+1; } else { right=mid; } } return left; //最後左右邊界重合,輸出任意一個邊界 } };