一个长度为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
方法:二分法
关键点:排序数组当中如果不缺项,那么应有:索引 = 索引处内容,即 nums[i]=inums[i] = inums[i]=i,如下图所示:
若当中出现缺项,则会导致其后所有位置索引 != 索引处内容,即 nums[i]!=inums[i] != inums[i]!=i ,如下图所示:
只需要找到第一个不匹配的数的索引2即可。
采用二分法搜索:
- 初始情况:i=0,j=nums[].size()−1,m=(i+j)/2i = 0,j = nums[].size()-1,m = (i+j)/2i=0,j=nums[].size()−1,m=(i+j)/2
- 若 nums[m]==mnums[m] == mnums[m]==m,则证明要找的数在区间[m+1,j][ m+1,j ][m+1,j]当中,此时可越过mmm。
- 若 nums[m]!=mnums[m] != mnums[m]!=m,则证明要找的数在区间[i,m][ i,m ][i,m],此时注意要包括mmm,有可能nums[m]nums[m]nums[m]就是要找的数。
- 当i==ji == ji==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;
}
};