剑指 Offer 53 - II. 0~n-1中缺失的数字

142 阅读1分钟

题目

一个长度为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这些数字在数组中是排序的,数字的索引和数字是相等的,所以缺失的数字就是第一个数字和索引下标不相等的的元素。因此,题目可以转换为在排序数组中找出第一个值与索引不相等的元素

基于二分查找的过程如下:

  1. 如果中间元素的值和索引相等,那么下一轮只要查找右半边,即mid + 1;
  2. 如果中间元素的值和索引不相等,分为以下几种情况:
    • 中间元素的前一个元素的值和索引相等,说明中间的元素是第一个值和索引不相等的元素
    • 中间元素的索引为0, 说明没有前一个元素,此时中间的元素就是第一个值和索引不相等的元素
    • 以上情况都不是,即中间元素的前一个元素的值与索引也不相等,那么下一轮只要查找左半边,即mid - 1
  3. 最后,二分查找结束,如果左指针等于数组的长度,说明缺失的数字就是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;
    }
};

原题链接

剑指 Offer 53 - II. 0~n-1中缺失的数字