剑指offer | 面试题53 - II. 0~n-1中缺失的数字_算法

开始行动,你已经成功一半了,献给正在奋斗的我们

 

题目

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字

示例:
输入: [0,1,3]
输出: 2

解题分析

首先这道题能想到的是,0-n-1,之内的所有数字,只有一个数字不在这个数组里面,那么我们的的做法就很简单了,我们可以先求出0-n-1的和是多少,数组里面不就是少一个数字么,我们用0-n-1的和减去数组里面的所有数字,得出来的就是缺少的那个数字,这种做法的时间复杂度为O(n);

但是,题目中给我们的是一个递增的数组,显然不仅仅是想让我们用这种方法来实现;我们可以使用二分法来处理这个问题;

我们来用计算机思维确认一下我们需要找的是什么数,缺失的那个数字,其实就是比它索引位置上要大1的数字,但是这样还不行,因为从那个确实数字之后的所有数字都比它的索引值要大,还必须得是第一个比它索引位置上要大1的数字的索引值就是我们要找的那个缺失的数字;

首先,为什么增强我们代码的健壮性,有一些特殊情况可以处理,比如,如果这个数组没有数字是空的,那么我们可以理解为这是一个长度为1的只有0的数组,缺失了元素0,于是返回0即可,如果长度是1,只有两种情况,0或1,是1的话缺少0,是0的话缺少1,我们直接1减去数组里面唯一的值返回即可,如果这个数组的最后一个元素还是等于它的索引值呢?说明他缺少最后一个元素,也就是数组的长度值,举例【0,1】就是【0,1,2】缺少【2】,【2】也恰好是【0,1】的长度;

剩下的事情,我们就可以直接进行二分查找,如果中间元素等于它的索引值,就说明目标值还在右边,我们让左指针加一,如果中间元素大于索引值,那就要看看中间元素前一个的元素是不是等于它的索引值(还有一种情况是前面没有元素,例如【1,2,3】,其实我们也找到了),如果是的话就返回结果(中间元素的索引值),如果没有,那就是答案还在左边,我们让右指针等于中间指针减一;理论上不存在中间元素小于索引值;

代码(JAVA实现)

ps:这里笔者使用的jdk为1.8版本

  • 求和相减法
public int missingNumber(int[] nums) {
        int sum = nums.length * (nums.length + 1) / 2;
        for (int num : nums) {
            sum -= num;
        }
        return sum;
    }
  • 二分法
class Solution {
    public int missingNumber(int[] nums) {
        if (Objects.isNull(nums) || nums.length == 0) {
            return 0;
        } else if (nums.length == 1) {
            return 1 - nums[0];
        } else if (nums[nums.length - 1] == nums.length - 1) {
            return nums.length;
        }

        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            // 这里是左节点加右节点的和除以2
            int mid = left  + ((right- left) >> 1);
            int num = nums[mid];
            if (num == mid) {
                left = mid + 1;
            } else if (num > mid && (mid - 1 < 0 || nums[mid - 1] == mid - 1)) {
                return mid;
            } else if (num > mid) {
                right = mid - 1;
            }
        }
        // 这种情况就是出现问题了
        return -1;
    }
}

剑指offer | 面试题53 - II. 0~n-1中缺失的数字_算法_02


剑指offer | 面试题53 - II. 0~n-1中缺失的数字_二分法_03
喜欢的朋友可以加我的个人微信,我们一起进步