代码
法一:枚举法
将正确的数组与实际的数组比较,易得实际数组arr[i]
大于真实数组p
。
arr[i] > p
时,说明存在缺失的整数,此时p++,并记录当前缺失的元素p
。等待相逢。arr[i] === p
时,说明此arr[i]
不是缺失的整数。- 当缺失的元素p的个数达到k时,结束循环。
/**
* @param {number[]} arr
* @param {number} k
* @return {number}
*/
var findKthPositive = function(arr, k) {
let p = 1 // 枚举
let pp = 0 // 数组遍历指针
for(let i = 0; i < k; p++) {
if(p === arr[pp]) {
pp = pp < arr.length ? (pp + 1) : (arr.length - 1)
}else {
i++
}
}
return (p - 1)
};
法二:arr[i] = i + 1
原理:
- 严格升序的正整数数组:
[1,2,3,4,5,6,7,...]
,可发现arr[i] = i + 1
的规律。 - 如果
arr[i] - i - 1
大于0,则表示存在缺失的整数,缺失个数为arr[i] - i - 1
的结果。
流程:
-
寻找
arr[i] - i - 1
大于等于k的arr[i]
,说明arr[i]之前就存在第k个缺失的整数
。
例如:arr = [2,3,4,7,11],k = 57 - 3 - 1 = 3 // 缺失3个 11 - 4 - 1 = 6 // 缺失6个
故第k个缺失的整数为
k + i
。 -
如果arr不存在
arr[i] - i - 1
大于等于K的arr[i]
,说明arr之外还有缺失的整数。根据最后一位arr[arr.length - 1]
的缺失个数和所需缺失个数之差,即可得到第K个缺失的正整数
。arr[arr.length - 1] - (arr[arr.length - 1] - (arr.length - 1) - 1) + k // 化简得 arr.length + k
故第k个缺失的整数为
arr.length + k
。
/**
* @param {number[]} arr
* @param {number} k
* @return {number}
*/
var findKthPositive = function(arr, k) {
for(let i = 0; i < arr.length; i++) {
if((arr[i] - i - 1) >= k) {
return k + i
}
}
return arr.length + k// 表明arr内缺失的数目不够k,arr外还有缺失,直接arr.length + k
};
总结
- 误区:题中
严格升序排列的正整数数组
是以1开头的数组,即[1, 2, 3, 4, 5, …]。