XOR
Three facts carry this entire page:
a ^ a = 0- anything cancels itselfa ^ 0 = a- zero is the identity- XOR is commutative and associative - order never matters
Together they make XOR self-inverse: applying it twice returns the original. That is why it both destroys duplicates and undoes its own encoding, and why you can fold an array in any order and get the same answer in O(1) space.
Its one blind spot: XOR only tracks parity. When values repeat an odd number of times other than one, cancellation stops working and you fall back to counting each bit position separately, mod 3.
Cancellation
Pairing values that should cancel exposes an imbalance even when it isn't a single repeated element: pair index against value to find a missing number, pair character ordinals across two strings, or keep a parity bitmask to test whether at most one character has an odd count. The same cancellation works with just two variables instead of a whole array: folding a value into its partner and unfolding it back out swaps them without a third variable to hold either one.
Swap The Numbers
XOR is self-inverse: a ^ a = 0 and a ^ 0 = a. After a = a ^ b, a holds the combined bits of both numbers. XOR-ing that combined value with b recovers the original a, so b = a ^ b sets b to the original a. XOR-ing again with the new b (the original a) strips it back out of the combined value, so a = a ^ b leaves a holding the original b. Three XORs, no third variable.
- Time
- O(1)
- Three XOR operations regardless of input size.
- Space
- O(1)
- No extra variable is used to hold either number.
Detect If Two Integers Have Opposite Signs
In two's complement, the sign bit (the most significant bit) is 1 for a negative number and 0 for a non-negative one. XOR-ing two numbers sets that bit only when the operands' sign bits differ, and any value with its sign bit set is negative - so x ^ y is negative exactly when x and y have opposite signs.
- Time
- O(1)
- A single XOR and comparison regardless of input size.
- Space
- O(1)
- No extra storage beyond the two inputs.
268. Missing Number
The array holds n distinct numbers drawn from 0, 1, ..., n. Seed the accumulator with n, then XOR in every index together with its value. Each number that is present appears once as an index and once as a value and cancels itself; the one missing number never gets cancelled and survives.
For [3, 0, 1]: 3 ^ (0^3) ^ (1^0) ^ (2^1) collapses to 2.
- Time
- O(N)
- One pass XOR-ing each index and value.
- Space
- O(1)
- A single accumulator.
389. Find the Difference
String t is a shuffle of s with one extra character. Treat each character as its code point and XOR every code from both strings together. Each shared character contributes its code twice and cancels (a ^ a = 0), so the surviving value is the code point of the added character. chr turns it back into the answer.
- Time
- O(2n)
- Two separate linear passes - one XOR fold over
s(ncharacters), one overt(n + 1characters) - eachO(n), giving2n, wheren = len(s). - Space
- O(1)
- A single accumulator.
266. Palindrome Permutation
A string can be rearranged into a palindrome when at most one character has an odd count. We track parity, not full counts: toggle the bit at position ord(char) - ord("a") for every character. A character seen an even number of times ends with its bit at 0; an odd number of times leaves it 1.
At the end, bitmask & (bitmask - 1) == 0 is true only when at most one bit is set - i.e. zero or one character has an odd count - which is exactly the palindrome condition.
- Time
- O(N)
- One toggle per character in the string.
- Space
- O(1)
- A single integer bitmask.
2206. Divide Array Into Equal Pairs
The array can be split into equal pairs only if every value appears an even number of times. XOR is the perfect parity tracker: toggling bit i with bitmask ^= (1 << i) for each value i flips that bit on every occurrence.
If every value occurs an even number of times, all bits cancel back to 0. So the array is pairable exactly when the final bitmask == 0.
- Time
- O(N)
- One pass toggling bits.
- Space
- O(1)
- A single integer mask (value range up to 500 bits).
Single Number
When every element pairs up except one, XOR the whole array: the pairs annihilate and the loner falls out. The same trick extends past the basic case - a lone element in an otherwise-sorted array of pairs still XORs out, three copies instead of two needs counting each bit mod 3 rather than plain XOR, and two loners hiding among pairs separate cleanly once you isolate a bit where they differ.
136. Single Number
XOR is commutative and associative, with two key identities: a ^ 0 = a and a ^ a = 0. So XOR-ing the entire array makes every value that appears twice cancel itself out, leaving only the unique number:
a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b
For [4, 1, 2, 1, 2] every pair cancels and 4 remains.
- Time
- O(n)
n = len(nums). One XOR intoxorper element in a single pass.- Space
- O(1)
- Only the
xoraccumulator is kept; nothing scales withn.
One odd Occuring
XOR is commutative and associative, with two key identities: a ^ 0 = a and a ^ a = 0. XOR-ing the entire array cancels every value that occurs an even number of times, no matter how many times it repeats, and leaves only the value that occurs an odd number of times.
- Time
- O(N)
- One XOR per element in a single pass.
- Space
- O(1)
- A single accumulator variable.
540. Single Element in a Sorted Array
Although the array is sorted, the same cancellation trick from 136. Single Number applies directly: every value appears twice except one, and XOR-ing the whole array makes the paired values cancel (a ^ a = 0), leaving the unique element.
The sorted order enables a faster O(log n) binary search, but this XOR fold is the simplest correct solution.
- Time
- O(N)
- One XOR per element across the array.
- Space
- O(1)
- A single accumulator.
137. Single Number II
Here every value appears three times except one. Plain XOR no longer works, so count instead. For each of the 32 bit positions, sum how many numbers have that bit set. Bits contributed by the tripled values sum to a multiple of 3; taking the count mod 3 leaves only the contribution of the lone number, which we OR back into the result.
A signed-integer guard fixes the sign bit: if the rebuilt value has bit 31 set, it represents a negative number in two's complement, so we subtract 2 ** 32.
- Time
- O(n)
- 32 fixed bit positions, each scanning all
nnumbers - linear inn. - Space
- O(1)
- A constant number of integer accumulators.
260. Single Number III
XOR the whole array first: every paired value cancels, leaving xor = a ^ b for the two lone numbers. a and b must differ in at least one bit, so mask = xor & (-xor) isolates the lowest bit where they differ. Splitting arr by whether each element has that bit set separates a from b into two independent single-number groups, each of which collapses under XOR to one of the answers.
- Time
- O(2N)
- Two separate
O(n)passes overarr: one to buildxor, one to split bymask-2n. - Space
- O(1)
- Only
xor,mask,a, andbare stored.
Fold & Invert a Sequence
Here XOR is used as a running accumulator rather than a duplicate-killer. Folding collapses a generated sequence into one value; inverting peels the original sequence back out of an encoded one, since encoded[i] = arr[i] ^ arr[i+1] rearranges to arr[i+1] = encoded[i] ^ arr[i]. Maximizing a XOR instead means choosing the partner whose high bits differ most.
1486. XOR Operation in an Array
The array is defined implicitly: element i is start + 2 * i. Instead of materializing it, we fold the XOR as we go.
Seed the accumulator with the first element (start), then XOR in each subsequent term start + 2 * i for i from 1 to n - 1. Because every term differs from its neighbour by a constant 2, no extra storage is needed - the running value carries all the information.
- Time
- O(n)
- The
for i in range(1, n)loop foldsn - 1terms intoxorin a single pass -O(n). - Space
- O(1)
- Only the running
xorvalue is stored.
1720. Decode XORed Array
The encoding rule is encoded[i] = arr[i] ^ arr[i + 1]. XOR is its own inverse, so XOR-ing both sides by arr[i] recovers the next element:
arr[i + 1] = encoded[i] ^ arr[i]
Starting from the known first, each step XORs the latest decoded value with the next encoded entry to peel off the following original element.
- Time
- O(N)
- One XOR per encoded element rebuilds the original array.
- Space
- O(N)
- The output array holds all
n + 1decoded elements.
2433. Find The Original Array of Prefix Xor
pref[i] is the running XOR of the original array up to index i, so pref[i] = arr[0] ^ ... ^ arr[i]. Consecutive prefixes differ by exactly one element:
pref[i] = pref[i - 1] ^ arr[i] ⇒ arr[i] = pref[i - 1] ^ pref[i]
The first element is just pref[0]. For every later index, XOR-ing adjacent prefix values cancels the shared history and leaves the single original element.
- Time
- O(N)
- One XOR of adjacent prefixes per element.
- Space
- O(N)
- The reconstructed array holds
nelements.
2683. Neighboring Bitwise XOR
derived[i] = original[i] ^ original[i + 1] (indices wrap for the last element). Seed original = [0] and invert the recurrence one step at a time: original[i + 1] = original[i] ^ derived[i]. Since the array wraps, original[len(derived)] should equal the seed original[0] if and only if a valid original exists - any other outcome means the wraparound XOR doesn't cancel out.
- Time
- O(N)
- One pass building
originalfromderived. - Space
- O(N)
- The reconstructed
originalarray holdsn + 1elements.
1829. Maximum XOR for Each Query
Each query removes the last element, so it asks for the XOR of a shrinking prefix. We process the elements left to right while keeping the running XOR of everything seen so far.
To maximize xor ^ k, pick the k that flips every bit of xor within the allowed maximumBit width - that is the all-ones mask 2 ** maximumBit - 1. XOR-ing the running value with that mask gives the answer for the current prefix. Because queries are answered in reverse order of array length, each result is inserted at the front.
- Time
- O(n^2)
- The
for i in numsloop runsntimes, wheren = len(nums), and each iteration's XOR update isO(1). ans.insert(0, ...)shifts every existing element ofansto make room at the front, which isO(i)on thei-th call; summed across allncalls that isO(n^2).- Space
- O(n)
ansholds one value per query, up tonentries.
2932. Maximum Strong Pair XOR I
A pair (i, j) is strong when abs(i - j) <= min(i, j). With the small constraints of this version, we simply try every ordered pair, keep only those that satisfy the strong condition, and track the largest XOR seen.
The double loop reuses each element as both endpoints, so self-pairs (i == j) are also considered - their XOR is 0 and never beats a real maximum.
- Time
- O(n²)
nis the length ofnums- the nestedfor i in nums: for j in nums:loops examine every ordered pair.- Space
- O(1)
- Only the running
maxiis stored, regardless of array length.