Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
An array holds n distinct numbers from the range [0, n] with exactly one missing. The math answer subtracts the actual sum from the expected sum n(n+1)/2. The overflow-safe answer XORs every index 0..n together with every value: each present number cancels with its index, leaving the missing one. Both are O(n) time, O(1) space.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you can find an O(1)-space solution beyond the obvious hash set — and whether you anticipate integer overflow in the sum approach and reach for XOR to sidestep it.
Where candidates slip
Using a hash set (O(n) space), or using the sum formula but computing n*(n+1)/2 in a way that overflows for large n, or seeding the XOR loop wrong so index n is never included.
How to stand out
Offer both the sum and XOR solutions, explain that XOR is overflow-safe, and explain WHY indices-XOR-values isolates the gap (each present number cancels its own index).
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachFirst decision previewOne number missing from [0, n]O(1) space required?NoYesExplore the full treeCollapse the tree
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Gauss Sum — Expected Minus Actual
1Hint 1Explore hintHide hint
If no number were missing, you'd know the exact total of 0 + 1 + ... + n. What's a closed form for that total?
2Hint 2Explore hintHide hint
The sum of 0..n is n(n+1)/2. The array's actual sum is short by exactly the missing value.
3Hint 3Explore hintHide hint
Compute expected = n(n+1)/2, subtract the sum of nums, and the remainder is the missing number.
A · Core idea
Compute the sum the array would have if nothing were missing — 0 + 1 + … + n = n(n+1)/2 — and subtract the array's actual sum. The shortfall is exactly the missing number.
Why the difference is the answer. The full range [0, n] sums to n(n+1)/2 (Gauss's formula). The array contains every one of those values except one, so its sum is the full sum minus the missing value. Rearranging: missing = expected − actual. It's pure conservation of total.
Why this is elegant but fragile. It's O(1) space and a clean one-liner of intent, but n(n+1)/2 and the running sum can both exceed the integer range for large n. In Java with int, n ≈ 10⁵ is safe, but a larger constraint or a 32-bit accumulator could silently overflow and return garbage. That fragility is exactly what the XOR approach removes — and naming the risk out loud is what separates a strong candidate.
A subtraction-as-you-go variant. You can fold expected and actual into a single accumulator: start at n, then for each index i add i and subtract nums[i]. This keeps the running value small and reduces overflow risk, though XOR is still the cleanest overflow-proof option.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
nums = [3, 0, 1]expected
n(n+1)/2 = 3·4/2
expected = 62C · Code with teaching comments
Reference implementation previewpublic int missingNumber(int[] nums) { int n = nums.length; int expected = n * (n + 1) / 2; int actual = 0; for (int x : nums) {Explore the full codeHide the full code
D · Why it works and complexityO(n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
This is a conservation argument: the total of a complete set is fixed, so any single omission shows up as an exact, computable deficit. The same 'expected total minus observed total' lever solves 'find the duplicate by sum' and 'find the corrupted entry' style problems.
ComplexityO(n) time, O(1) space — One pass to sum the array is O(n); the expected sum is a constant-time formula. Only a couple of accumulators → O(1) space.
E · Edge cases and pitfalls5nums = [0] — n = 1, expected = 1, actual = 0 → missing = 1 (the top endpoint).Explore edge casesHide edge cases
Edge cases handled
nums = [0]n = 1, expected = 1, actual = 0 → missing = 1 (the top endpoint).nums = [1]n = 1, expected = 1, actual = 1 → missing = 0 (the bottom endpoint).
Pitfalls
- Integer overflow on n*(n+1)/2 or the running sum for large n in fixed-width types.
- Using n = nums.length but indexing the range as [0, n-1] instead of [0, n] — off by one.
- Computing n*(n+1) before dividing in a narrow type, doubling the overflow risk.
Approach 2 of 2 · Optimal
XOR Indices With Values (Optimal)
1Hint 1Explore hintHide hint
Recall a ^ a = 0. If you XOR a complete set of numbers against the array's values, what cancels and what survives?
2Hint 2Explore hintHide hint
XOR together all indices 0..n AND all array values. Every present value v has a matching index equal to v, so they pair up and vanish.
3Hint 3Explore hintHide hint
Seed the accumulator with n (since indices in the loop only go to n-1), then XOR in both i and nums[i] each step.
A · Core idea
XOR together two things: every index in 0..n and every value in the array. Because the values are a subset of 0..n missing exactly one element, each present value cancels against the identical index, and the lone index with no matching value survives — that's the missing number.
Why pairing index with value cancels. Think of XOR-ing the multiset {0,1,…,n} ∪ {all nums}. Every number that is present appears twice — once as an index, once as a value — and a ^ a = 0 annihilates each such pair. The missing number appears only once (as an index 0..n, never as a value), so it alone is left standing.
Why we seed with `n`. The loop variable i only reaches n − 1 (array length is n), but the range of possible answers is 0..n inclusive. Seeding the accumulator with n injects that final index so the full index set 0..n is represented. A common bug is forgetting this seed, which fails whenever the answer is n itself.
Why XOR beats the sum. XOR never overflows — it's a fixed set of bit operations with no carry growth. The sum approach can exceed the integer range for large n; XOR cannot. Same O(n) time and O(1) space, strictly safer. That's why, when an interviewer asks 'what if n is huge?', XOR is the clean reply.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
nums = [3, 0, 1]Array state
seed
acc = 3 (the index n)
2C · Code with teaching comments
D · Why it works and complexityO(n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
This is the Single Number trick generalised: instead of pairing duplicate values, you pair indices with values. Any time you have a complete labelled set with one element absent (or duplicated), XOR of labels against contents isolates the anomaly in O(1) space without arithmetic overflow.
ComplexityO(n) time, O(1) space — One pass doing two constant-time XORs per element is O(n); a single accumulator is O(1) space. No multiplication means no overflow.
E · Edge cases and pitfalls5nums = [0] — Seed 1, then ^= 0 ^ 0 = 0 → result 1. Missing top endpoint handled by the n seed.Explore edge casesHide edge cases
Edge cases handled
nums = [0]Seed 1, then ^= 0 ^ 0 = 0 → result 1. Missing top endpoint handled by the n seed.nums = [1]Seed 1, then ^= 0 ^ 1 → 1 ^ 0 ^ 1 = 0 → result 0. Missing bottom endpoint.
Pitfalls
- Forgetting to seed with n — fails whenever the missing number is n itself.
- XOR-ing only the values or only the indices instead of both — you must pair them.
- Treating this like Single Number and pairing values with values — here it's indices against values.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int missingNumber(int[] nums) { int missing = nums.length; for (int i = 0; i < nums.length; i++) { missing ^= i ^ nums[i]; }Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Forgetting the XOR seed of n
The loop index only reaches n - 1, so the value n is never XOR-ed in. If the missing number is n, the result is wrong unless you seed the accumulator with n.
Explore the code comparisonHide the code comparison
Forgetting the XOR seed of n
The loop index only reaches n - 1, so the value n is never XOR-ed in. If the missing number is n, the result is wrong unless you seed the accumulator with n.
Don't write this
int missing = 0; // should start at n
for (int i = 0; i < nums.length; i++) {
missing ^= i ^ nums[i];
}
return missing; // fails when answer is nWrite this instead
int missing = nums.length; // seed with n covers the full range
for (int i = 0; i < nums.length; i++) {
missing ^= i ^ nums[i];
}
return missing;2Overflow in the sum approach
n*(n+1) can exceed Integer.MAX_VALUE before the divide, producing a wrong expected sum. Use a long, fold subtraction into the loop, or prefer XOR.
Explore the code comparisonHide the code comparison
Overflow in the sum approach
n*(n+1) can exceed Integer.MAX_VALUE before the divide, producing a wrong expected sum. Use a long, fold subtraction into the loop, or prefer XOR.
Don't write this
int expected = n * (n + 1) / 2; // n*(n+1) overflows int for large nWrite this instead
long expected = (long) n * (n + 1) / 2; // promote to long before multiplyingRevise
Carry the pattern into the interview
Pattern to remember
Index–value pairing (XOR cancellation / sum difference)
Code pattern to memorize
missing = n
for i, x in enumerate(nums):
missing ^= i ^ x # indices 0..n-1 XOR all values, seed n
return missingRules to remember
- 1Seed the XOR with n so the full index set
0..nis covered (the loop only reaches indexn-1). - 2Every value that IS present cancels with its matching index via
a ^ a = 0; the missing number has no value to cancel its index. - 3The sum formula
n(n+1)/2 − Σnumsis the same idea arithmetically, but can overflow for large n; XOR never overflows. - 4Both run in O(n) time and O(1) space — no sorting, no hash set needed.
- 5Don't confuse this with Single Number: here you pair indices with values, not values with their duplicates.
Use this pattern when
- Find the one missing element from a contiguous range [0, n]
- Numbers are distinct and span a known complete range minus one
- You want O(1) space and want to avoid overflow → XOR variant
- A 'one element absent from 1..n' framing of any kind
Choose another pattern when
- Multiple numbers missing → XOR/sum collapse them together; use a boolean array or set
- Range has duplicates → the pairing logic breaks (that's Find the Duplicate)
- Numbers aren't a contiguous range → no expected sum/index structure to exploit
- You also need WHICH indices are present, not just the gap → use a presence array
Interview takeaway
Missing Number is two clean O(1)-space tricks wearing one prompt: Gauss's sum minus the actual sum, or XOR of indices against values. The XOR version is the one to prefer aloud — it's immune to integer overflow, which is the exact gotcha interviewers probe on the sum approach.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternIndex–value pairing for the odd one out. Recognise it when a contiguous range [0, n] is missing exactly one element. XOR (overflow-safe) or expected-minus-actual sum both isolate the gap in O(1) space — the same conservation idea behind Single Number.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Single NumberThe pure XOR-cancellation parent: pair duplicate values instead of indices with values.
- Find All Numbers Disappeared in an ArrayComing soonMultiple missing numbers — XOR/sum collapse them, so mark presence in-place by negating indices.
- Find the Duplicate NumberComing soonRange with a duplicate instead of a gap — Floyd's cycle detection on the value-as-pointer graph.
- First Missing PositiveComing soonFind the smallest missing positive — index-as-hash placement, O(1) space, harder cousin.