1060. Missing Element in Sorted Array
Problem Description
You are given an integer array nums that is sorted in ascending order, where all elements are unique. You're also given an integer k.
The task is to find the kth missing number in the sequence, starting from the leftmost (first) element of the array.
A "missing number" is any integer that should appear in the continuous sequence starting from nums[0] but is not present in the array. For example:
- If
nums = [4, 7, 9, 10]andk = 1, the first missing number starting from 4 would be 5 (since 5 is not in the array). - If
k = 2, the second missing number would be 6. - If
k = 3, the third missing number would be 8.
The solution uses binary search to efficiently find the kth missing number. The helper function missing(i) calculates how many numbers are missing up to index i by using the formula: nums[i] - nums[0] - i. This works because in a continuous sequence with no missing numbers, the element at index i would be nums[0] + i.
The algorithm first checks if k is greater than the total number of missing elements in the array range. If so, it calculates the answer by extending beyond the last element. Otherwise, it uses binary search to find the position where exactly k missing numbers have occurred, then calculates the kth missing number based on that position.
Intuition
The key insight is recognizing that we can calculate how many numbers are missing up to any position in the array without actually listing them out.
Think about it this way: if we have a perfectly continuous sequence starting from nums[0], the element at index i should be nums[0] + i. For example, if nums[0] = 4, then ideally we'd have [4, 5, 6, 7, ...]. But in reality, we might have [4, 7, 9, ...] where some numbers are skipped.
The difference between what we actually have (nums[i]) and what we should have (nums[0] + i) tells us exactly how many numbers are missing up to that point. This gives us the formula: missing(i) = nums[i] - nums[0] - i.
Once we can efficiently count missing numbers at any position, finding the kth missing number becomes a search problem. We need to find where in the array the count of missing numbers transitions from less than k to at least k.
Since the array is sorted and the count of missing numbers is monotonically increasing (we can only have more missing numbers as we go further, never fewer), we can use binary search. We're essentially searching for the leftmost position where we have at least k missing numbers.
The edge case is when k is larger than all the missing numbers within the array range. In this case, the kth missing number must be beyond the last element of the array, and we can calculate it directly by extending from the last element.
Learn more about Binary Search patterns.
Solution Implementation
1class Solution:
2 def missingElement(self, nums: List[int], k: int) -> int:
3 """
4 Find the k-th missing element in a sorted array.
5
6 Args:
7 nums: A sorted array of integers
8 k: The k-th missing number to find
9
10 Returns:
11 The k-th missing integer
12 """
13
14 def count_missing_before_index(index: int) -> int:
15 """
16 Calculate how many numbers are missing before nums[index].
17
18 The missing count is the difference between:
19 - The actual range covered (nums[index] - nums[0])
20 - The number of elements present (index)
21 """
22 return nums[index] - nums[0] - index
23
24 n = len(nums)
25
26 # Check if k-th missing element is beyond the array's last element
27 total_missing_in_range = count_missing_before_index(n - 1)
28 if k > total_missing_in_range:
29 # The k-th missing element is after the last element
30 # Add the remaining missing count to the last element
31 return nums[n - 1] + k - total_missing_in_range
32
33 # Binary search to find the first index where missing count >= k
34 # Feasible condition: count_missing_before_index(mid) >= k
35 # Pattern: [false, false, ..., true, true, true]
36 left, right = 0, n - 1
37 first_true_index = -1
38
39 while left <= right:
40 mid = (left + right) // 2
41
42 if count_missing_before_index(mid) >= k:
43 # Feasible: this index has at least k missing numbers before it
44 first_true_index = mid
45 right = mid - 1
46 else:
47 # Not feasible: need more missing numbers, search right
48 left = mid + 1
49
50 # The k-th missing element is between nums[first_true_index-1] and nums[first_true_index]
51 # Calculate its exact value by adding the remaining count to nums[first_true_index-1]
52 return nums[first_true_index - 1] + k - count_missing_before_index(first_true_index - 1)
531class Solution {
2 /**
3 * Find the k-th missing element in a sorted array.
4 * The k-th missing element is the k-th positive integer that is missing from the array.
5 *
6 * @param nums A sorted array of distinct integers
7 * @param k The k-th missing element to find (1-indexed)
8 * @return The k-th missing element
9 */
10 public int missingElement(int[] nums, int k) {
11 int n = nums.length;
12
13 // Check if k-th missing element is beyond the last element of array
14 // If so, calculate directly from the last element
15 if (k > countMissingBeforeIndex(nums, n - 1)) {
16 return nums[n - 1] + k - countMissingBeforeIndex(nums, n - 1);
17 }
18
19 // Binary search to find the first index where missing count >= k
20 // Feasible condition: countMissingBeforeIndex(mid) >= k
21 // Pattern: [false, false, ..., true, true, true]
22 int left = 0;
23 int right = n - 1;
24 int firstTrueIndex = -1;
25
26 while (left <= right) {
27 int mid = left + (right - left) / 2;
28
29 if (countMissingBeforeIndex(nums, mid) >= k) {
30 // Feasible: this index has at least k missing numbers before it
31 firstTrueIndex = mid;
32 right = mid - 1;
33 } else {
34 // Not feasible: need more missing numbers, search right
35 left = mid + 1;
36 }
37 }
38
39 // Calculate the k-th missing element based on the element before firstTrueIndex
40 return nums[firstTrueIndex - 1] + k - countMissingBeforeIndex(nums, firstTrueIndex - 1);
41 }
42
43 /**
44 * Calculate the number of missing elements before index i (inclusive).
45 * Missing elements are the positive integers that should exist between nums[0] and nums[i]
46 * but are not present in the array.
47 *
48 * @param nums The sorted array
49 * @param i The index to check up to (inclusive)
50 * @return The count of missing elements before index i
51 */
52 private int countMissingBeforeIndex(int[] nums, int i) {
53 // Total range from nums[0] to nums[i] is (nums[i] - nums[0])
54 // Actual elements present in this range is (i + 1) including both endpoints
55 // So missing elements = total range - actual elements present
56 return nums[i] - nums[0] - i;
57 }
58}
591class Solution {
2public:
3 int missingElement(vector<int>& nums, int k) {
4 // Lambda function to calculate how many numbers are missing before index i
5 // Formula: (actual value at i) - (expected value if no gaps) = missing count
6 // Expected value at index i would be nums[0] + i if there were no gaps
7 auto countMissingBeforeIndex = [&](int index) {
8 return nums[index] - nums[0] - index;
9 };
10
11 int arraySize = nums.size();
12
13 // Check if the k-th missing number is beyond the array's range
14 // If so, calculate it directly from the last element
15 if (k > countMissingBeforeIndex(arraySize - 1)) {
16 return nums[arraySize - 1] + k - countMissingBeforeIndex(arraySize - 1);
17 }
18
19 // Binary search to find the first index where missing count >= k
20 // Feasible condition: countMissingBeforeIndex(mid) >= k
21 // Pattern: [false, false, ..., true, true, true]
22 int left = 0;
23 int right = arraySize - 1;
24 int firstTrueIndex = -1;
25
26 while (left <= right) {
27 int mid = left + (right - left) / 2;
28
29 if (countMissingBeforeIndex(mid) >= k) {
30 // Feasible: this index has at least k missing numbers before it
31 firstTrueIndex = mid;
32 right = mid - 1;
33 } else {
34 // Not feasible: need more missing numbers, search right
35 left = mid + 1;
36 }
37 }
38
39 // The k-th missing number is between nums[firstTrueIndex-1] and nums[firstTrueIndex]
40 // Calculate it based on nums[firstTrueIndex-1] plus the remaining missing numbers needed
41 return nums[firstTrueIndex - 1] + k - countMissingBeforeIndex(firstTrueIndex - 1);
42 }
43};
441function missingElement(nums: number[], k: number): number {
2 // Helper function to calculate how many numbers are missing before index i
3 // Formula: (actual value at i) - (expected value if no gaps) = missing count
4 // Expected value at index i would be nums[0] + i if there were no gaps
5 const countMissingBeforeIndex = (index: number): number => {
6 return nums[index] - nums[0] - index;
7 };
8
9 const arraySize = nums.length;
10
11 // Check if the k-th missing number is beyond the array's range
12 // If so, calculate it directly from the last element
13 if (k > countMissingBeforeIndex(arraySize - 1)) {
14 return nums[arraySize - 1] + k - countMissingBeforeIndex(arraySize - 1);
15 }
16
17 // Binary search to find the first index where missing count >= k
18 // Feasible condition: countMissingBeforeIndex(mid) >= k
19 // Pattern: [false, false, ..., true, true, true]
20 let left = 0;
21 let right = arraySize - 1;
22 let firstTrueIndex = -1;
23
24 while (left <= right) {
25 const mid = Math.floor((left + right) / 2);
26
27 if (countMissingBeforeIndex(mid) >= k) {
28 // Feasible: this index has at least k missing numbers before it
29 firstTrueIndex = mid;
30 right = mid - 1;
31 } else {
32 // Not feasible: need more missing numbers, search right
33 left = mid + 1;
34 }
35 }
36
37 // The k-th missing number is between nums[firstTrueIndex-1] and nums[firstTrueIndex]
38 // Calculate it based on nums[firstTrueIndex-1] plus the remaining missing numbers needed
39 return nums[firstTrueIndex - 1] + k - countMissingBeforeIndex(firstTrueIndex - 1);
40}
41Solution Approach
The solution implements a binary search algorithm with a helper function to efficiently find the kth missing number.
Helper Function:
The missing(i) function calculates the count of missing numbers up to index i:
- Formula:
nums[i] - nums[0] - i - This represents the difference between the actual value at index
iand what it should be in a continuous sequence
Main Algorithm Steps:
-
Check if k exceeds array bounds:
- Calculate total missing numbers in the array:
missing(n - 1) - If
k > missing(n - 1), the answer lies beyond the array - Return:
nums[n - 1] + k - missing(n - 1) - This adds the remaining missing numbers to the last element
- Calculate total missing numbers in the array:
-
Binary Search Using the Template:
- Feasible condition:
missing(mid) >= k- does this index have at least k missing numbers before it? - This creates a pattern:
[false, false, ..., true, true, true] - We want to find the first
trueindex - Initialize:
left = 0,right = n - 1,first_true_index = -1 - Loop while
left <= right:- Calculate
mid = (left + right) // 2 - If
missing(mid) >= k(feasible): recordfirst_true_index = mid, then search left withright = mid - 1 - Otherwise: search right with
left = mid + 1
- Calculate
- Feasible condition:
-
Calculate the Result:
- After binary search,
first_true_indexis the first index where we have at leastkmissing numbers - The
kth missing number is between indicesfirst_true_index - 1andfirst_true_index - Return:
nums[first_true_index - 1] + k - missing(first_true_index - 1) - This formula adds the remaining missing numbers needed to reach
kfrom the previous position
- After binary search,
Time Complexity: O(log n) due to binary search
Space Complexity: O(1) as we only use a few variables
The elegance of this solution lies in avoiding the enumeration of all missing numbers and instead using mathematical relationships to directly compute the answer.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with nums = [4, 7, 9, 10] and k = 3.
Step 1: Calculate missing numbers at each index
Using the formula missing(i) = nums[i] - nums[0] - i:
- Index 0:
missing(0) = 4 - 4 - 0 = 0(no missing numbers before 4) - Index 1:
missing(1) = 7 - 4 - 1 = 2(numbers 5 and 6 are missing) - Index 2:
missing(2) = 9 - 4 - 2 = 3(numbers 5, 6, and 8 are missing) - Index 3:
missing(3) = 10 - 4 - 3 = 3(same 3 missing numbers)
Step 2: Check if k exceeds array bounds
- Total missing in array:
missing(3) = 3 - Since
k = 3is not greater than 3, we proceed with binary search
Step 3: Binary Search Using Template
- Feasible condition:
missing(mid) >= k - Initialize:
left = 0,right = 3,first_true_index = -1
Iteration 1:
left = 0, right = 3mid = (0 + 3) // 2 = 1missing(1) = 2 < k = 3→ NOT feasible- Move left pointer:
left = 2
Iteration 2:
left = 2, right = 3mid = (2 + 3) // 2 = 2missing(2) = 3 >= k = 3→ Feasible!- Record:
first_true_index = 2 - Move right pointer:
right = 1
Iteration 3:
left = 2, right = 1left > right, loop ends
Step 4: Calculate the result
first_true_index = 2, so we look at positionfirst_true_index - 1 = 1missing(1) = 2(we have 2 missing numbers by index 1)- We need
k - missing(1) = 3 - 2 = 1more missing number - Result:
nums[1] + (k - missing(1)) = 7 + 1 = 8
Verification: The missing numbers in order are: 5, 6, 8. The 3rd missing number is indeed 8.
Time and Space Complexity
Time Complexity: O(log n)
The algorithm uses binary search to find the position where the k-th missing element would be. The missing(i) helper function calculates how many numbers are missing up to index i in constant time O(1). The binary search loop runs for O(log n) iterations where n is the length of the input array. Each iteration performs constant time operations including calling missing(), comparisons, and index calculations. Therefore, the overall time complexity is O(log n).
Space Complexity: O(1)
The algorithm uses only a constant amount of extra space. The variables l, r, mid, and n are all integers that occupy constant space. The helper function missing(i) doesn't create any additional data structures and only performs arithmetic operations. No recursive calls are made, so there's no additional stack space usage beyond the function call itself. Therefore, the space complexity is O(1).
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Using the Wrong Binary Search Template
A common mistake is using while left < right with right = mid instead of the standard template with while left <= right and first_true_index tracking.
Pitfall Example:
# Incorrect: Using alternative template while left < right: mid = (left + right) // 2 if count_missing_before_index(mid) >= k: right = mid else: left = mid + 1 return nums[left - 1] + k - count_missing_before_index(left - 1)
Why it's problematic: This variant works but differs from the standard template pattern. The standard template explicitly tracks the answer with first_true_index, making the logic clearer.
Solution: Use the standard template with while left <= right and first_true_index:
first_true_index = -1 while left <= right: mid = (left + right) // 2 if count_missing_before_index(mid) >= k: first_true_index = mid right = mid - 1 else: left = mid + 1
2. Incorrect Final Calculation Formula
Another common error is using the wrong index or formula when calculating the final result.
Pitfall Example:
# Incorrect: Using nums[left] instead of nums[left - 1] return nums[left] + k - count_missing_before_index(left)
Why it fails: After binary search, left points to the first position where we have at least k missing numbers. The k-th missing number lies between nums[left-1] and nums[left], not after nums[left].
Solution: Use nums[left - 1] + k - count_missing_before_index(left - 1) to correctly calculate from the previous position.
3. Not Handling Edge Case When k=1 and left=0
When the first missing number occurs before the first element, accessing nums[left - 1] causes an index error.
Pitfall Example:
# If nums = [5, 7, 9] and k = 1, the first missing is before index 0 # After binary search, left = 0 return nums[left - 1] + k - count_missing_before_index(left - 1) # IndexError!
Solution: Add a special check for when left == 0:
if left == 0: # All k missing numbers come before the first element return nums[0] - k else: return nums[left - 1] + k - count_missing_before_index(left - 1)
4. Misunderstanding the Missing Count Formula
Developers sometimes incorrectly calculate the missing count by forgetting to subtract the starting position.
Pitfall Example:
# Incorrect: Not accounting for the starting position
def count_missing_before_index(index):
return nums[index] - index # Wrong! Assumes sequence starts at 0
Why it fails: If nums = [4, 7, 9], this would incorrectly calculate missing(0) = 4, when actually no numbers are missing before index 0 (since we start counting from 4).
Solution: Always use nums[index] - nums[0] - index to correctly count missing numbers relative to the starting element.
Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?
Recommended Readings
https assets algo monster cover_photos Binary_Search svg Binary Search Intuition Binary search is an efficient array search algorithm It works by narrowing down the search range by half each time If you have looked up a word in a physical dictionary you've already used binary search in real life Let's
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Want a Structured Path to Master System Design Too? Don’t Miss This!