📜  未排序数组中的第 k 个缺失元素(1)

📅  最后修改于: 2023-12-03 15:10:39.806000             🧑  作者: Mango

LeetCode题解:未排序数组中的第 k 个缺失元素

题目描述

给定一个按照升序排列的正整数数组 nums ,和一个整数 k 。数组中的每个数字表示你在工作时间内获得的工资,工资按时间顺序从第 1 天(下标为 0)开始递增。

请你返回 前 k 个缺失的数字 ,使得它们被加起来等于targe。

示例1:

输入: nums = [4,7,9,10], k = 3
输出: [5,6,8]
解释:
第一个缺失数字为 5 ,因为它没有出现在 nums 中。
第二个缺失数字为 6 ,因为它没有出现在 nums 中。
第三个缺失数字为 8 ,因为它没有出现在 nums 中。
所以答案是 [5,6,8] 。

示例2:

输入: nums = [1,2,4], k = 5
输出: [6,7,8,9,10]
解释: 
前 5 个缺失数字为 [3,5,6,7,8] ,因为它们没有出现在 nums 中。
所以答案是 [6,7,8,9,10] 。

提示:

  • 1 <= nums.length <= $5 \times 10^4$
  • 1 <= nums[i] <= $10^7$
  • nums 中的数字是按升序排列的。
  • 1 <= k <= $10^8$
解法

这道题目可以使用二分查找的方法,在每一次查找时,都记录当前已经找到了多少个缺失元素。

初始时,左边界为 0,右边界为 nums.size()。然后进行二分查找,查找到第一个大于等于 x 的位置 i,说明 [0, i - 1] 这段区间内都是不缺失元素的,而 [i, nums.size() - 1] 这段区间内还有未查找的缺失元素。所以我们将答案更新为 x + k + (i - 1),即第 k 个缺失元素为 x + k + (i - 1)

然后将左边界更新为 i,继续进行二分查找,重复上述过程直到找到了 k 个缺失元素。

代码如下:

class Solution {
public:
    int missing(int x, vector<int>& nums) {
        int l = 0, r = nums.size();
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return l;
    }

    vector<int> findMissingRanges(vector<int>& nums, int k) {
        vector<int> res;
        int x = 0;
        for (int i = 0; i < nums.size() && k > 0; ++i) {
            if (x == nums[i]) {
                ++x;
                continue;
            }
            int cnt = missing(x, nums);
            if (cnt == i) {
                res.push_back(x);
                ++x;
                k--;
            }
        }
        while (k > 0) {
            res.push_back(x + k - 1);
            k--;
        }
        return res;
    }
};
总结

本题的解法比较简单。

以下是本题的完整代码:

class Solution {
public:
    int missing(int x, vector<int>& nums) {
        int l = 0, r = nums.size();
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return l;
    }

    vector<int> findMissingRanges(vector<int>& nums, int k) {
        vector<int> res;
        int x = 0;
        for (int i = 0; i < nums.size() && k > 0; ++i) {
            if (x == nums[i]) {
                ++x;
                continue;
            }
            int cnt = missing(x, nums);
            if (cnt == i) {
                res.push_back(x);
                ++x;
                k--;
            }
        }
        while (k > 0) {
            res.push_back(x + k - 1);
            k--;
        }
        return res;
    }
};