LCOF 53 - II. 0~n-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

2. 标签

  • 数组

  • 二分查找

3. 解法 - 二分查找

3.1 Java

class Solution {
    public int missingNumber(int[] nums) {
        // 数组最左端
        int left = 0;
        // 数组最右端
        int right = nums.length - 1;
        
        /**
         * 由题意,数组可以分为两部分:
         *  左子数组中每个 nums[i] = i
         *  右子数组中每个 nums[i] != i
         * 
         * 所以题目中想求的就是「右子数组的首位元素」对应的索引
         * 此处采用二分法来查找该元素
         */
        while (left<=right) {
            // 中点
            int mid = left + (right - left) / 2;

            if (nums[mid] == mid) {
                // 此时,「右子数组的首位元素」一定处于[mid + 1, right]中
                // 所以接下来应该开始搜索当前元素的右边
                left = mid + 1;
            } else {
                // 此时,「左子数组的末位元素」一定处于[left, mid - 1]中
                // 所以接下来应该开始搜索当前元素的左边
                right = mid - 1;
            }
        }
        // 返回 left 和 right 都可以,退出上面的循环之后他俩是相同的!
        return left;
    }
}

3.2 Kotlin

class Solution {
    fun missingNumber(nums: IntArray): Int {
        // 数组最左端
        var left = 0
        // 数组最右端
        var right = nums.size - 1

        /**
         * 由题意,数组可以分为两部分:
         * 左子数组中每个 nums[i] = i
         * 右子数组中每个 nums[i] != i
         *
         * 所以题目中想求的就是「右子数组的首位元素」对应的索引
         * 此处采用二分法来查找该元素
         */
        while (left <= right) {
            // 中点
            val mid = left + (right - left) / 2

            if (nums[mid] == mid) {
                // 此时,「右子数组的首位元素」一定处于[mid + 1, right]中
                // 所以接下来应该开始搜索当前元素的右边
                left = mid + 1
            } else {
                // 此时,「左子数组的末位元素」一定处于[left, mid - 1]中
                // 所以接下来应该开始搜索当前元素的左边
                right = mid - 1
            }
        }
        // 返回 left 和 right 都可以,退出上面的循环之后他俩是相同的!
        return left
    }
}

3.3 复杂度分析

  • 时间复杂度 O(logN) :搜索空间每次循环都会减少一半,二分查找的时间复杂度为对数级别。

  • 空间复杂度 O(1) :只使用了常数大小的存储空间。

4. 参考

最后更新于