Leetcode尊享面试100题:1060. 有序数组中的缺失元素

现有一个按 升序 排列的整数数组 nums ,其中每个数字都 互不相同

给你一个整数 k ,请你找出并返回从数组最左边开始的第 k 个缺失数字。

示例 1:

复制代码
输入:nums = [4,7,9,10], k = 1
输出:5
解释:第一个缺失数字为 5 。

示例 2:

复制代码
输入:nums = [4,7,9,10], k = 3
输出:8
解释:缺失数字有 [5,6,8,...],因此第三个缺失数字为 8 。

示例 3:

复制代码
输入:nums = [1,2,4], k = 3
输出:6
解释:缺失数字有 [3,5,6,7,...],因此第三个缺失数字为 6 。

提示:

  • 1 <= nums.length <= 5 * 104
  • 1 <= nums[i] <= 107
  • nums升序 排列,其中所有元素 互不相同
  • 1 <= k <= 108

进阶: 你可以设计一个对数时间复杂度(即,O(log(n)))的解决方案吗?

直接上代码,不会的可以私信或者留言:

java 复制代码
class Solution {
    //基础的解法是:数一下每两个数之间缺几个数,如果从头开始数到这个区间仍然小于k,就用k
    //剪去这个区间缺的数量,如果大于等于k了就停止
    public int missingElement2(int[] nums, int k) {
        int remains = k;
        //每个区间都不缺就是缺在最后一个数的后面
        int stopIndex = nums.length - 1;
        for(int i = 1;i < nums.length; i++) {
            //i-1~i这个区间缺了多少个数
            int missingInCurRange = nums[i] - nums[i - 1] - 1;
            //如果这个区间缺的数还是不够就继续搜索下个区间
            if(missingInCurRange < remains) {
                remains -= missingInCurRange;
            } else {
                //否则缺的数就在本区间,本区间的起点是i-1
                stopIndex = i - 1;
                break;
            }
        }
        return nums[stopIndex] + remains;
    }

    //进阶的解法,如果要实现logn的解法,必定是使用二分查找,我也想不到什么特别好的方案
    //只能说我试试,比如找到数组中某个位置,如果到以这个位置为起点的区间确实的数小于等于k就继续尝试找更大的
    //符合缺失数小于等于k的,如果大于k就往回找
    public int missingElement(int[] nums, int k) {
        //如果就一个数,缺k个就用第一个数+k返回
        if(nums.length == 1) {
            return nums[0] + k;
        }
        //使用二分法查找:区间结尾怎么也得是下标为1的位置了,最大是nums.length - 1
        int l = 1;
        int r = nums.length - 1;
        //没有证明前面的区间缺这么多的时候只能认为是在最后一个数的后面缺
        int endIndex = nums.length;
        //二分查找
        while(l <= r) {
            int mid = l + (r - l)/2;
            //到mid这个位置结尾的区间缺了多少个数
            int missingCount = missingCount(nums, mid);
            //如果到mid结尾的位置已经超过k个了,说明就在这个区间或者在上一个区间
            if(missingCount >= k) {
                //先记录一个答案,然后继续往前找
                endIndex = mid;
                r = mid - 1;
            } else {
                //不够k说明还得继续往后
                l = mid + 1;
            }
        }
        /**在0~endIndex-1这个区间缺了多少个数,如果不缺的话应该是nums[endIndex - 1] - nums[0] + 1个数
        但是现在只有endIndex个数,所以缺了(nums[endIndex - 1] - nums[0] + 1) - endIndex个*/
        int preMissing = ((nums[endIndex - 1] - nums[0] + 1) - endIndex);
        return nums[endIndex - 1] + (k - preMissing);
    }
    //到以index这个位置为终点的区间一共缺失了多少个数
    public int missingCount(int[] nums, int index) {
        return nums[index] - nums[0] + 1 - (index + 1);
    }
}

运行效果:

相关推荐
小O的算法实验室2 天前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
风止何安啊2 天前
为什么要有 TypeScript?让 JS 告别 “薛定谔的 Bug”
前端·javascript·面试
郭涤生2 天前
STL vector 扩容机制与自定义内存分配器设计分析
c++·算法
༾冬瓜大侠༿2 天前
vector
c语言·开发语言·数据结构·c++·算法
Ricky111zzz2 天前
leetcode学python记录1
python·算法·leetcode·职场和发展
汀、人工智能2 天前
[特殊字符] 第58课:两个正序数组的中位数
数据结构·算法·数据库架构··数据流·两个正序数组的中位数
liu****2 天前
第16届省赛蓝桥杯大赛C/C++大学B组(京津冀)
开发语言·数据结构·c++·算法·蓝桥杯
汀、人工智能2 天前
[特殊字符] 第79课:分割等和子集
数据结构·算法·数据库架构·位运算·哈希表·分割等和子集
汀、人工智能2 天前
[特殊字符] 第74课:完全平方数
数据结构·算法·数据库架构·图论·bfs·完全平方数
CoderCodingNo2 天前
【GESP】C++四、五级练习题 luogu-P1177 【模板】排序
数据结构·c++·算法