Skip to content
← All posts

Single Number: XOR Cancellation in One Pass

3 min read
leetcodeproblemeasyarraysbit-manipulation

LeetCode Single Number (Problem 136) asks: given a non-empty array of integers nums, every element appears exactly twice except for one. Find that single one.

The constraints are strict. You must run in linear time and use constant extra space. That rules out hash maps, sets, and sorting. The intended tool is XOR.

The XOR cancellation property

XOR is a bitwise operation. It compares two bits and outputs 1 when they differ, 0 when they match. In Python, the operator is ^.

Three properties make XOR perfect for this problem:

a ^ a = 0pairs cancel0 ^ b = bidentitya ^ b = b ^ a order irrelevant
The three XOR properties. Pairs cancel to 0, zero preserves any value, and order does not matter.

When you XOR all elements of an array together, every number that appears twice cancels itself to 0. And XOR-ing with 0 leaves the remaining number untouched. The pairs vanish. The single number survives.

The approach

The algorithm is almost absurdly simple:

  1. Initialize result = 0
  2. XOR every element into result
  3. Return result

Because XOR is commutative and associative, the order of elements does not matter. Pairs will always find each other and cancel to 0, regardless of where they sit in the array.

Python solution

def single_number(nums: list[int]) -> int:
    result = 0
    for num in nums:
        result ^= num
    return result

Walkthrough: [4, 1, 2, 1, 2]

Let's trace the algorithm on [4, 1, 2, 1, 2]. The answer should be 4, since 1 and 2 each appear twice.

Step 1: XOR with nums[0] = 4. result = 0 ^ 4 = 4

4011221324currentrunning XOR:4100

Starting from 0. XOR with 4 gives 4 (binary: 100).

Step 2: XOR with nums[1] = 1. result = 4 ^ 1 = 5

4011221324currentrunning XOR:5101

4 (100) ^ 1 (001) = 5 (101). Two different bits flip on.

Step 3: XOR with nums[2] = 2. result = 5 ^ 2 = 7

4011221324currentrunning XOR:7111

5 (101) ^ 2 (010) = 7 (111). All three bits are on now.

Step 4: XOR with nums[3] = 1. result = 7 ^ 1 = 6

4011221324currentrunning XOR:6110

7 (111) ^ 1 (001) = 6 (110). The 1 cancels out. It appeared at index 1 and again here.

Step 5: XOR with nums[4] = 2. result = 6 ^ 2 = 4

4011221324currentrunning XOR:4100

6 (110) ^ 2 (010) = 4 (100). The 2 cancels out too. Only 4 remains.

When 1 appeared the second time (step 4), its bits cancelled against the first occurrence. When 2 appeared the second time (step 5), the same thing happened. Only the bits from 4 survived the entire pass.

You do not need to group pairs next to each other. XOR is commutative and associative, so the cancellation happens automatically regardless of element order.

Complexity analysis

ApproachTimeSpace
Brute force (nested loops)O(n^2)O(1)
Hash map countingO(n)O(n)
SortingO(n log n)O(1)*
XOR cancellationO(n)O(1)

*Sorting is O(1) extra space only if done in-place, but it modifies the input array.

XOR wins on both dimensions: linear time and constant space with no side effects.

The building blocks

This problem decomposes into one reusable building block that CodeBricks drills independently:

XOR cancellation (accumulate XOR across a collection)

Initialize a result to 0 and XOR every element into it. Pairs cancel to 0, and only unpaired values survive. This micro-pattern is the backbone of duplicate cancellation, missing element detection, and parity-based reasoning across many problems.

result = 0
for item in collection:
    result ^= item

The pattern is deceptively simple. It is just a loop with ^=. But recognizing when to reach for it is the real skill. Whenever a problem says "every element appears twice except one" or "find the missing element in a range," XOR accumulation should be your first instinct.

Edge cases

Single element array. If nums has only one element, the loop XORs that element with 0 and returns it immediately. 0 ^ x = x, so the answer is correct.

Large arrays. XOR is a constant-time bitwise operation. Whether the array has 10 elements or 10 million, each step takes the same amount of work. The algorithm stays O(n) regardless of scale.

Negative numbers. XOR works on the binary representation of integers, including negative numbers stored in two's complement. (-3) ^ (-3) = 0 just like 3 ^ 3 = 0. The cancellation property holds for any integer value.

From understanding to recall

Reading through the XOR cancellation property is the first step. But in an interview, you need the pattern to fire instantly when you see the right signals. That recall gap is where most people get stuck.

The fix is deliberate practice. You drill the XOR accumulation pattern as an isolated building block, typing it from scratch at increasing intervals. After a few repetitions, you stop thinking about bit-level mechanics. You see "pairs cancel" and the code flows out of your fingers.

That is the difference between understanding a solution and owning it.

Related posts

  • XOR Cancellation Pattern - A deep dive into XOR from the ground up, including the truth table, all three properties, and extended variants like finding two non-repeating numbers.
  • Number of 1 Bits - Another bit manipulation problem. Uses n & (n - 1) to clear the lowest set bit, a different but complementary technique to XOR.