Prerequisites
Before attempting this problem, you should be comfortable with:
- Arithmetic Progression - Understanding how to calculate the common difference and expected values at each position in a sequence
- Binary Search - The optimal solution uses binary search to locate the missing element by comparing actual vs expected values
1. Linear search
Intuition
An arithmetic progression has a constant difference between consecutive elements. Since exactly one element is missing, we can compute what the common difference should be using the first and last elements: difference = (arr[n-1] - arr[0]) / n. Then we walk through the array, checking if each element matches the expected value. The first mismatch reveals the missing number.
Algorithm
- Calculate the common difference:
difference = (arr[n - 1] - arr[0]) / n. - Initialize
expected = arr[0]. - Iterate through each element in the array:
- If the current element does not equal
expected, returnexpectedas the missing number. - Otherwise, increment
expectedbydifference.
- If the current element does not equal
- If no mismatch is found during iteration, return the final
expectedvalue as the missing number.
class Solution:
def missingNumber(self, arr: List[int]) -> int:
n = len(arr)
# Get the difference `difference`.
difference = (arr[-1] - arr[0]) // n
# The expected element equals the starting element.
expected = arr[0]
for val in arr:
# Return the expected value that doesn't match val.
if val != expected:
return expected
# Next element will be expected element + `difference`.
expected += difference
return expectedTime & Space Complexity
- Time complexity:
- Space complexity: constant space
Where is the length of array
arr.
2. Binary Search
Intuition
Since the array is sorted and follows an arithmetic progression, we can use binary search to locate the missing element faster. At any index i, the expected value is arr[0] + i * difference. If the actual value matches, all elements up to that index are correct, so the missing number is to the right. If there is a mismatch, the missing number is at or before that index. This allows us to narrow down the search space logarithmically.
Algorithm
- Calculate the common difference:
difference = (arr[n - 1] - arr[0]) / n. - Initialize
lo = 0andhi = n - 1. - While
lo < hi:- Compute
mid = (lo + hi) / 2. - If
arr[mid]equals the expected valuearr[0] + mid * difference, the missing element is aftermid, so setlo = mid + 1. - Otherwise, the missing element is at or before
mid, so sethi = mid.
- Compute
- Return
arr[0] + difference * loas the missing number that should be at indexlo.
class Solution:
def missingNumber(self, arr: List[int]) -> int:
n = len(arr)
# Get the difference `difference`.
difference = (arr[n - 1] - arr[0]) // n
lo = 0
hi = n - 1
# Basic binary search template.
while lo < hi:
mid = (lo + hi) // 2
# All numbers up to `mid` have no missing number, so search on the right side.
if arr[mid] == arr[0] + mid * difference:
lo = mid + 1
# A number is missing before `mid` inclusive of `mid` itself.
else:
hi = mid
# Index `lo` will be the position with the first incorrect number.
# Return the value that was supposed to be at this index.
return arr[0] + difference * loTime & Space Complexity
- Time complexity:
- Space complexity: constant space
Where is the length of array
arr.
Common Pitfalls
Incorrect Common Difference Calculation
The common difference must be calculated as (arr[n-1] - arr[0]) / n, not (arr[n-1] - arr[0]) / (n-1). Since one element is missing, the full sequence would have n+1 elements with n gaps, making the divisor n.
Not Handling Zero Difference
When the common difference is zero (all elements are the same), any position could be the "missing" element since the missing value equals all existing values. The linear search returns the first element in this case, which is correct.
Integer Division Truncation
In languages where division truncates toward zero, negative arithmetic progressions may produce incorrect common differences. Ensure the division correctly handles both positive and negative sequences.