📅  最后修改于: 2023-12-03 15:10:39.806000             🧑  作者: Mango
给定一个按照升序排列的正整数数组 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] 。
提示:
这道题目可以使用二分查找的方法,在每一次查找时,都记录当前已经找到了多少个缺失元素。
初始时,左边界为 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;
}
};