nums
res ^ i ^ nums[i] column by column: a 1 when the column has an odd number of 1s
0 … n, XORed in an odd number of times each number enters once as an index or as n, and once as a value · res = XOR of the lit ones
public int missingNumber(int[] nums) { int res = nums.length; // n: the one index the loop skips for (int i = 0; i < nums.length; i++) { res ^= i ^ nums[i]; } return res;}
- i
- —
- nums[i]
- —
- res
- —
Why it works
- Brute force: sort and look for the first index where
nums[i] != i(O(n log n)), or put the values in aHashSetand test 0 … n (O(n) space). - Pair every number with itself. XOR all indices 0 … n − 1, plus n, and all values. Each number from 0 to n shows up once on the index side; every number except the missing one also shows up once on the value side. Pairs cancel (
x ^ x = 0), so only the missing number survives. - One pass, one integer: O(n) time, O(1) space. XOR cannot overflow, unlike a running sum in an
int. - Pitfall: n itself.
i < nums.lengthstops at n − 1, so n would never get its index-side partner. Startingresatnums.lengthadds it. Without that, an input missing n returns a wrong answer. - Alternative: Gauss's sum,
n·(n + 1)/2 − (sum of nums), or the same loop withres += i − nums[i]. Single Number (136) is the same cancellation trick.