这是我参与「掘金日新计划 · 2 月更文挑战」的第 27 天,点击查看活动详情
问题描述
给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。
请你找到这个数组里第 k 个缺失的正整数。
示例 1:
输入: arr = [2,3,4,7,11], k = 5
输出: 9
解释: 缺失的正整数包括 [1,5,6,8,9,10,12,13,...] 。第 5 个缺失的正整数为 9 。
示例 2:
输入: arr = [1,2,3,4], k = 2
输出: 6
解释: 缺失的正整数包括 [5,6,7,...] 。第 2 个缺失的正整数为 6 。
提示:
1 <= arr.length <= 10001 <= arr[i] <= 10001 <= k <= 1000- 对于所有
1 <= i < j <= arr.length的i和j满足arr[i] < arr[j]
进阶:
你可以设计一个时间复杂度小于 O(n) 的算法解决此问题吗?
思路分析
首先我们先要理解一下题目意思,题目会给我们一个数组和一个整数,我们需要找到arr中缺失的第k个正整数,如arr = [2,3,4,7,11], k = 5,缺失的正整数包括 [1,5,6,8,9,10,12,13,...] 。第 5 个缺失的正整数为 9 。
- 遍历求值
最简单的方法是直接从1开始往后遍历,判断元素是否在arr中,不在的话则说明为缺失的元素,此时缺失元素计数加一,当计数为k时则说明找到了第k个缺失的正整数,代码如下:
/**
* @param {number[]} arr
* @param {number} k
* @return {number}
*/
var findKthPositive = function (arr, k) {
let i = 0,
ind = 0;
while (k) {
i++;
if (arr[ind] == i) ind++;
else k--;
}
return i;
};
上述的方法的时间复杂度为O(n),那么有没有时间复杂度小于 O(n) 的算法可以解决此问题呢?答案是有的,我们可以直接计算arr中相邻两个元素之间的差值得出两元素间缺失的元素数量,当缺失元素数量达到k个时,我们即可快速计算出第k个缺失的正整数,具体代码如下:
/**
* @param {number[]} arr
* @param {number} k
* @return {number}
*/
var findKthPositive = function (arr, k) {
for (let i = 0; i < arr.length; i++) {
const dif = arr[i] - (arr[i - 1] || 0) - 1;
if (k - dif <= 0) return (arr[i - 1] || 0) + k;
k -= dif;
}
return arr[arr.length - 1] + k;
};
说在后面
本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。