You are given a sorted array of distinct positive integers arr
and an integer k
. Your task is to find the k
-th missing positive integer that is not present in arr
.
arr
contains only positive integers, sorted in strictly increasing order.k
-th smallest positive integer that does not appear in arr
).Constraints:
arr
.arr = [2, 3, 4, 7, 11]
, k = 5
9
At first glance, you might want to generate all positive integers, skipping those in arr
, and count until you reach the k
-th missing number. However, this brute-force approach is inefficient if k
is large or arr
is long.
By thinking more deeply, we realize that since arr
is sorted and contains only positive numbers, we can efficiently count how many numbers are missing up to each position in arr
. The difference between the current value and its index (plus one) tells us how many numbers are missing before that position. This insight allows us to jump directly to the answer without checking every integer.
So, the key is to:
k
-th missing number fits in relation to arr
.k
is before, within, or after the last element of arr
.Let's break down the steps to solve the problem efficiently:
arr[i]
, the number of missing positive integers before it is arr[i] - (i + 1)
.
arr[0] = 2
, then 2 - 1 = 1
number is missing before arr[0]
(which is 1).
arr
and track missing numbers:
k
.
k
-th missing number is between arr[i-1]
and arr[i]
.
k
is greater than the number of missing numbers before the last element, then the answer is beyond the last element of arr
: arr[-1] + (k - missing_before_last)
.
arr[i-1] + (k - missing_before_prev)
.
arr
is sorted, we can use binary search to find the first index where the number of missing numbers is greater than or equal to k
, which makes the solution much faster for large inputs.
This approach ensures we never scan more than necessary, making the solution efficient and elegant.
Let's use arr = [2, 3, 4, 7, 11]
and k = 5
as our example.
2 - 1 = 1
(missing: 1)3 - 2 = 1
(still just 1 missing: 1)4 - 3 = 1
(still just 1 missing: 1)7 - 4 = 3
(missing: 1,5,6; so total missing up to here is 3)11 - 5 = 6
(missing: 1,5,6,8,9,10; total missing up to here is 6)arr[3]
: 3arr[3] + (k - missing_before_3) = 7 + (5 - 3) = 9
9
arr
, and count missing until k
is reached.
k
is very large).
arr
.
arr
of length n
.
The key insight is that the number of missing numbers up to each index in arr
can be calculated directly using arr[i] - (i + 1)
. By leveraging binary search, we can efficiently pinpoint where the k
-th missing positive integer falls, making the solution both fast and elegant. This approach avoids unnecessary iteration and demonstrates the power of mathematical reasoning and search algorithms in array problems.
class Solution:
def findKthPositive(self, arr, k):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
missing = arr[mid] - (mid + 1)
if missing < k:
left = mid + 1
else:
right = mid - 1
return left + k
class Solution {
public:
int findKthPositive(vector<int>& arr, int k) {
int left = 0, right = arr.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int missing = arr[mid] - (mid + 1);
if (missing < k)
left = mid + 1;
else
right = mid - 1;
}
return left + k;
}
};
class Solution {
public int findKthPositive(int[] arr, int k) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int missing = arr[mid] - (mid + 1);
if (missing < k) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left + k;
}
}
var findKthPositive = function(arr, k) {
let left = 0, right = arr.length - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
let missing = arr[mid] - (mid + 1);
if (missing < k) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left + k;
};