题目
一个长度为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这些数字在数组中是排序的,数字的索引和数字是相等的,所以缺失的数字就是第一个数字和索引下标不相等的的元素。因此,题目可以转换为在排序数组中找出第一个值与索引不相等的元素
基于二分查找的过程如下:
- 如果中间元素的值和索引相等,那么下一轮只要查找右半边,即
mid + 1; - 如果中间元素的值和索引不相等,分为以下几种情况:
- 中间元素的前一个元素的值和索引相等,说明中间的元素是第一个值和索引不相等的元素
- 中间元素的索引为0, 说明没有前一个元素,此时中间的元素就是第一个值和索引不相等的元素
- 以上情况都不是,即中间元素的前一个元素的值与索引也不相等,那么下一轮只要查找左半边,即
mid - 1
- 最后,二分查找结束,如果左指针等于数组的长度,说明缺失的数字就是
nums.length, 即n-1;
参考代码
/**
* @param {number[]} nums
* @return {number}
*/
var missingNumber = function(nums) {
let left = 0, right = nums.length;
while(left <= right) {
let mid = (left + right) >> 1;
if (nums[mid] == mid) {
left = mid + 1;
} else {
if (nums[mid - 1] == mid-1 || mid == 0) {
return mid;
} else {
right = mid - 1;
}
}
}
if (left === nums.length) {
return nums.length;
}
};