class Solution:
def missingElement(self, nums, k):
def missing(idx):
return nums[idx] - nums[0] - idx
n = len(nums)
if k > missing(n - 1):
return nums[-1] + k - missing(n - 1)
left, right = 0, n - 1
while left < right:
mid = (left + right) // 2
if missing(mid) < k:
left = mid + 1
else:
right = mid
return nums[left - 1] + k - missing(left - 1)
class Solution {
public:
int missingElement(vector<int>& nums, int k) {
auto missing = [&nums](int idx) {
return nums[idx] - nums[0] - idx;
};
int n = nums.size();
if (k > missing(n - 1))
return nums[n - 1] + k - missing(n - 1);
int left = 0, right = n - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (missing(mid) < k)
left = mid + 1;
else
right = mid;
}
return nums[left - 1] + k - missing(left - 1);
}
};
class Solution {
public int missingElement(int[] nums, int k) {
int n = nums.length;
int missing = nums[n - 1] - nums[0] - (n - 1);
if (k > missing)
return nums[n - 1] + k - missing;
int left = 0, right = n - 1;
while (left < right) {
int mid = left + (right - left) / 2;
int miss = nums[mid] - nums[0] - mid;
if (miss < k)
left = mid + 1;
else
right = mid;
}
int missLeft = nums[left - 1] - nums[0] - (left - 1);
return nums[left - 1] + k - missLeft;
}
}
var missingElement = function(nums, k) {
function missing(idx) {
return nums[idx] - nums[0] - idx;
}
let n = nums.length;
if (k > missing(n - 1))
return nums[n - 1] + k - missing(n - 1);
let left = 0, right = n - 1;
while (left < right) {
let mid = Math.floor((left + right) / 2);
if (missing(mid) < k)
left = mid + 1;
else
right = mid;
}
return nums[left - 1] + k - missing(left - 1);
};
Given a sorted array of unique integers nums and an integer k, find the k-th missing number starting from the first element of nums. The array is strictly increasing, and all elements are unique.
k-th missing number.nums can be used only once; do not reuse elements.
Example:
If nums = [4,7,9,10], and k = 3, the missing numbers are 5, 6, 8. The 3rd missing number is 8.
The first idea is to enumerate all numbers between nums[0] and nums[-1], counting which are missing. For each gap between consecutive elements, we can count how many numbers are skipped. However, this brute-force approach can be slow if the numbers are large or the array is long.
To optimize, notice that the number of missing elements up to index i is nums[i] - nums[0] - i. This counts how many numbers are "skipped" from the start up to nums[i]. Using this, we can efficiently find where the k-th missing number falls, and even use binary search to speed it up.
If k is larger than the total number of missing numbers within the array, the answer must be after the last element. Otherwise, we can pinpoint the "gap" where the k-th missing occurs.
missing(idx) that returns the number of missing numbers up to index idx: nums[idx] - nums[0] - idx.
k is greater than the total number of missing numbers in the array (i.e., missing(n-1)). If so, the answer is past the last element: nums[-1] + k - missing(n-1).
left where missing(left) >= k. This means the k-th missing number lies just before nums[left].
nums[left-1] + k - missing(left-1), which shifts forward from the last known number by the remaining missing count needed to reach k.
missing() function quickly tells us how many numbers are missing up to any index.
Example:
nums = [4,7,9,10], k = 3
missing(0) = 4-4-0 = 0missing(1) = 7-4-1 = 2missing(2) = 9-4-2 = 3missing(3) = 10-4-3 = 3k=3 is not greater than this, we use binary search:
nums[1] + k - missing(1) = 7 + 3 - 2 = 8
8.
nums[0] and nums[-1] takes O(N + D) time, where D is the difference between first and last element. This can be slow for large gaps.
missing(idx) is O(1).
The key insight is to use the formula nums[i] - nums[0] - i to quickly count missing numbers up to any index. By combining this with binary search, we efficiently find where the k-th missing number falls, even for large arrays and big gaps. This approach is both elegant and optimal, reducing time from linear to logarithmic while using constant space.