0~n-1中缺失的數字
阿新 • • 發佈:2021-01-25
技術標籤:資料結構和演算法
一個長度為n-1的遞增排序陣列中的所有數字都是唯一的,並且每個數字都在範圍0~n-1之內。在範圍0~n-1內的n個數字中有且只有一個數字不在該陣列中,請找出這個數字。
輸入: [0,1,3]
輸出: 2
輸入: [0,1,2,3,4,5,6,7,9]
輸出: 8
特殊例子:
輸入: [0]
輸出: 1
輸入:[1]
輸出: 0
最直接的思路就是按照陣列遍歷, 找出下標和值不對應的數字, 如果沒有就是nums.count, 時間複雜度是O(N).
class Solution { func missingNumber(_ nums: [Int]) -> Int { for (i,num) in nums.enumerated() { if (i == num) { } else { return i } } return nums.count } }
優化下, 自然是用二分法了, 先找中間位置的數字,
- 中間位置的數字 == 下表, 說明缺失的數字在後半部分, 並且不可能是此值, 所以用left = index+1
- 中間位置的數字 != 下表, 說明缺失的數字在前半部分, 同時也有可能是本身,所以index不能減1
最後還有2個特殊的值, 頭部值和尾部值,
- 頭部就判斷是否等於0, 等於0, 說明正常; 不等於0, 那缺失的就是此數字
- 尾部判斷是否等於count-1, 如果相等, 那就是缺了最後一個數字; 如果不相等, 說明缺失的數字在0~count-1之間
class Solution { func missingNumber(_ nums: [Int]) -> Int { let count = nums.count // 特殊用例, 如果最後一個都符合條件, 那就是count不滿足 if nums[count-1] == count-1 { return count } // 頭部不滿足條件,返回0 if nums[0] != 0 { return 0 } // 開始二分查詢 var left = 0 var right = count-1 while left<right { // 找到中間位置的數字 let index = (left+right)/2 // 中間位置數字相等,說明在後半部分, if index == nums[index] { left = index+1 } else { // 中間位置數字不相等,說明在前半部分,也有可能是本身,所以index不能減1 right = index } } return left } }