LeetCode #268 Easy

Missing Number

Given an array holding n distinct numbers drawn from the range 0..n, find the one value from that range that is absent.

mathbit-manipulationarray
Open on LeetCode ↗
02

Intuition

💡

The answer everyone writes is n*(n+1)//2 - sum(nums), and in Python it passes. In C++ or Java with a large n it silently overflows: the triangular number grows quadratically, so it blows past a 32-bit int long before n itself does, and you get a wrapped-around garbage subtraction. The fix is not a bigger integer type — it is picking an operation that cannot overflow in the first place. XOR never grows a number; it only rearranges bits, so the result always fits in the same width as its inputs. Now use the property that makes XOR useful: a ^ a = 0 and a ^ 0 = a. Fold every index 0..n and every value in the array into one running accumulator, and each number that is genuinely present appears twice — once as an index, once as a value — and annihilates itself. The missing number appears exactly once, as an index with no matching value, so it is the only thing left standing. That is the invariant: at every step, the accumulator holds the XOR of exactly those numbers seen an odd number of times.

03

Approach

1

Reject the sum formula for the right reason

The Gauss sum is elegant and O(n), so it is not wrong on complexity — it is wrong on arithmetic safety. For n near 100,000 the triangular number already exceeds 5 billion, past the 32-bit signed ceiling, and in a fixed-width language the value wraps. The result may even come out right by accident when both sides wrap identically, which makes it a bug that hides in testing. Reaching for an overflow-immune operation is the durable habit.

2

Pair each index with each value using XOR

The array has n slots but the range 0..n holds n+1 candidates. Walk the array once and fold in both the loop index i and the element nums[i]. Every value that is actually present will get XOR-ed in twice — once when its index comes up, once when it appears as an element — and those two copies cancel to zero. XOR is commutative and associative, so the order of the folding is irrelevant; the pairs find each other no matter how the array is shuffled.

3

Fold in n by hand, because the loop never reaches it

The loop index only runs 0 to n-1, so the candidate n itself is never offered. XOR it in explicitly, either before or after the loop, and now every one of the n+1 candidates has been contributed exactly once as an index. Combined with the n values from the array, that gives every present number exactly two appearances and the missing number exactly one. Whatever survives is the answer.

04

Solution & live demo

python
1class Solution:
2 def missingNumber(self, nums: List[int]) -> int:
3 x = 0
4 for i, v in enumerate(nums):
5 x ^= i ^ v
6 x ^= len(nums)
7 return x
05

Edge cases

The missing number is 0, e.g. nums = [1,2]

0 XOR-ed in as an index has no matching value to cancel it — but XOR-ing 0 changes nothing, so the pairs cancel to 0 and 0 is correctly returned.

The missing number is n, e.g. nums = [0,1]

The manual fold of n is what supplies it; without that line this case returns 0 instead.

Single element, nums = [0]

Fold index 0, value 0, and n = 1: the zeros cancel and 1 survives, which is correct.

Large n where the sum formula would overflow

XOR operates bitwise and never produces a value wider than its inputs, so the range of n is irrelevant.

06

Complexity

Time
O(n)
Space
O(1)
A single pass with one accumulator — and unlike the sum formula, the accumulator can never exceed the width of the values it folds.