Single Number
Every value in the array appears twice except one. Find the value that appears alone, using no extra memory.
- value
- 0
- bits
- 0000
Start at zero and XOR everything in. Nothing is ever compared.
1def single_number(nums):2 result = 03 for n in nums:4 result ^= n5 return resultRead the 7 steps as text
- 1Start at zero and XOR everything in. Nothing is ever compared.
- 20000 XOR 0111 = 0111, so the running value is 7.
- 30111 XOR 0010 = 0101, so the running value is 5.
- 40101 XOR 0101 = 0000 โ that pair has cancelled itself out.
- 50000 XOR 0010 = 0010, so the running value is 2.
- 60010 XOR 0111 = 0101, so the running value is 5.
- 7Every pair cancelled. What survives is the unpaired value: 5.
The idea
A hash set solves this immediately, and it's a perfectly good first answer โ but it costs O(n) memory, and the problem specifically asks for constant space. That constraint is a hint about which tool is wanted.
XOR has three properties that, taken together, are the whole solution. A value XOR'd with itself is 0. Anything XOR'd with 0 is unchanged. And XOR is both commutative and associative, so the order you combine things in does not matter.
That last one is what makes the pairs cancel even though they're scattered. XOR-ing the entire array is the same as first grouping each pair together โ every pair collapses to 0, all those zeros collapse to 0, and the lone value passes through untouched.
So the answer isn't found, it's accumulated. There is no comparison anywhere in the algorithm.
The approach
- 1Start an accumulator at 0.
- 2XOR every element into it, in whatever order the array happens to be in.
- 3Whatever remains is the unpaired value.
Complexity
One pass and one integer, regardless of how large the values are.
Code
def single_number(nums):
result = 0
for n in nums:
result ^= n
return resultWhat goes wrong
- โขStarting the accumulator at the first element and then XOR-ing it again in the loop, which cancels it out.
- โขAssuming this generalises. If elements appear three times instead of two, XOR no longer cancels them and you need bit-counting modulo 3 โ a genuinely different technique with the same flavour.
- โขUsing `+` and `โ` instead. It works only if you already know the distinct values, which you don't.