一个长度为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
方法:二分法
关键点:排序数组当中如果不缺项,那么应有:索引 = 索引处内容,即 n u m s [ i ] = i nums[i] = i nums[i]=i,如下图所示:
若当中出现缺项,则会导致其后所有位置索引 != 索引处内容,即
n
u
m
s
[
i
]
!
=
i
nums[i] != i
nums[i]!=i ,如下图所示:
只需要找到第一个不匹配的数的索引2即可。
采用二分法搜索:
- 初始情况: i = 0 , j = n u m s [ ] . s i z e ( ) − 1 , m = ( i + j ) / 2 i = 0,j = nums[].size()-1,m = (i+j)/2 i=0,j=nums[].size()−1,m=(i+j)/2
- 若 n u m s [ m ] = = m nums[m] == m nums[m]==m,则证明要找的数在区间 [ m + 1 , j ] [ m+1,j ] [m+1,j]当中,此时可越过 m m m。
- 若 n u m s [ m ] ! = m nums[m] != m nums[m]!=m,则证明要找的数在区间 [ i , m ] [ i,m ] [i,m],此时注意要包括 m m m,有可能 n u m s [ m ] nums[m] nums[m]就是要找的数。
- 当 i = = j i == j i==j时输出即可。
特殊情况:当缺少的数为最后一个时,如:
输入: [0,1,2]
输出: 3
我们可以找到规律,当缺少的数不是最后一个时,数组中的最后一个数是等于数组长度的,若不等,则就是此种特殊情况,此时直接输出数组长度即可。
C++
class Solution {
public:
int missingNumber(vector<int>& nums) {
int l = nums.size();
if (nums[l-1] != l) return l;
int i = 0,j = l-1;
while(i<j){
int m = (i+j) / 2;
if(m==nums[m]) i = m+1;
else j = m;
}
return i;
}
};