Bit Manipulation
Treat integers as rows of 32 switches and use XOR, AND, OR and shifts to cancel duplicates, count bits, encode sets and do arithmetic in O(1) space.
Instinct Pairs that cancel, counting 1s, powers of two, subsets as numbers, or 'no + or - allowed' - drop to binary and use XOR, AND, OR and shifts.
Memory hack XOR is a forgetful twin detector - see something twice and it vanishes; n & (n-1) snips off the last lit bulb.
At a glance
When to use it
- Every value appears twice except one, or one number is missing from 0..n
- You need to count set bits, test a power of two or reverse bits
- Arithmetic operators are banned (add without + or -)
- n is small (about 20 or less) and every subset can be a bitmask
Key idea
Treat each integer as 32 switches and use XOR to cancel pairs, n & (n-1) to drop the lowest set bit and shifts to move bits, turning hash-set or loop-heavy solutions into O(n) time with O(1) extra space.
Typical complexity
O(n) time, O(1) space
| # | Common problems | Level | Our solution | Practice |
|---|---|---|---|---|
| 1 | Single Number | Easy | Read solution | LeetCode ↗ |
| 2 | Number of 1 Bits | Easy | Read solution | LeetCode ↗ |
| 3 | Counting Bits | Easy | Read solution | LeetCode ↗ |
| 4 | Missing Number | Easy | Read solution | LeetCode ↗ |
| 5 | Reverse Bits | Easy | Read solution | LeetCode ↗ |
| 6 | Sum of Two Integers | Medium | Read solution | LeetCode ↗ |
The instinct
Every int is secretly an array of 32 booleans that the CPU can flip, combine and slide in a single instruction. Bit manipulation problems reward you for noticing that the question is really about parity, presence, or binary structure rather than about magnitude. If a hash set would work but the interviewer asks for O(1) extra space, or the problem says "without using + or -", the answer is almost always hiding in the bits.
Recognise it
| Signal in the problem | Why it points here |
|---|---|
| "every element appears twice except one" | x ^ x = 0 and x ^ 0 = x, so XOR of everything leaves the loner. |
| "number of 1 bits / Hamming weight / Hamming distance" | n & (n - 1) clears the lowest set bit; count how many times you can do it. |
| "is it a power of two / power of four" | A power of two has exactly one set bit. |
| "add two integers without + or -" | XOR is sum-without-carry, AND shifted left is the carry. |
| "missing number in 0..n" | XOR indices with values; every present number cancels. |
| "reverse bits / unsigned 32-bit integer" | Shift bits out of one end and into the other, 32 times. |
| "AND of all numbers in a range" | The answer is the common binary prefix of the endpoints. |
| "n is at most 16-20, try every subset" | A mask from 0 to 2^n - 1 enumerates subsets. |
Not this pattern if...
- Duplicates can appear an arbitrary number of times and you need counts - use a hash map or counting array.
- Values are huge (beyond 64 bits) or the question is really about decimal digits - use math or strings.
- "Subsets" have n around 40+ - 2^n masks are too many; think backtracking with pruning or meet-in-the-middle.
Memory hack
"XOR is a forgetful twin detector; n & (n-1) snips the last lit bulb." XOR remembers only what it has seen an odd number of times. n & (n - 1) turns off the rightmost 1, while n & -n keeps only that rightmost 1.
Analogy: a row of light switches in a hallway. AND asks "are both lights on?", OR asks "is either on?", XOR asks "are they different?", and a shift slides every switch one door over. Flipping a switch twice leaves the hallway as it was - that is why paired numbers cancel.
Say it out loud in the interview:
- "What property survives in binary - parity, a single set bit, or a shared prefix?"
- "Which identity do I need:
x ^ x = 0,n & (n-1),n & -n, or(n >> i) & 1?" - "Am I safe on negatives and overflow - should I use
>>>and along?"
How it works
The toolbox is small - learn these six moves and most problems become a two-line loop:
| Goal | Expression |
|---|---|
| Read bit i | (n >> i) & 1 |
| Set / clear / toggle bit i | n | (1 << i), n & ~(1 << i), n ^ (1 << i) |
| Drop lowest set bit | n & (n - 1) |
| Isolate lowest set bit | n & -n |
| Bits in 0..n via DP | bits[i] = bits[i >> 1] + (i & 1) |
| Add without + | sum = a ^ b, carry = (a & b) << 1, repeat until carry is 0 |
Worked trace for Sum of Two Integers, a = 5 (0101), b = 3 (0011):
| Step | a (partial sum) | b (carry) |
|---|---|---|
| start | 0101 | 0011 |
| 1 | 0110 (5 ^ 3) | 0010 ((5 & 3) << 1) |
| 2 | 0100 | 0100 |
| 3 | 0000 | 1000 |
| 4 | 1000 = 8 | 0000 -> stop |
For Single Number III (two loners), XOR everything to get x ^ y, isolate any set bit with d & -d - x and y differ there - then split the array into two groups by that bit and XOR each group separately.
Java template
class BitTricks { // XOR fold: whatever appears an odd number of times survives. static int xorAll(int[] nums) { int acc = 0; for (int x : nums) acc ^= x; return acc; } // Kernighan: loop runs once per set bit, works for negatives too. static int popCount(int n) { int count = 0; while (n != 0) { n &= n - 1; count++; } return count; } // Walk all 32 positions; use >>> so the sign bit does not smear. static int reverseBits(int n) { int result = 0; for (int i = 0; i < 32; i++) { result = (result << 1) | (n & 1); n >>>= 1; } return result; } // Arithmetic without + : XOR is the sum, AND<<1 is the carry. static int add(int a, int b) { while (b != 0) { int carry = (a & b) << 1; a ^= b; b = carry; } return a; } // Subset enumeration: each mask is one subset of n items. static void forEachSubset(int n) { for (int mask = 0; mask < (1 << n); mask++) { for (int i = 0; i < n; i++) { if (((mask >> i) & 1) == 1) { // item i is in this subset - problem-specific work here } } } } }
Complexity
| Operation | Time | Space |
|---|---|---|
| XOR fold over the array | O(n) | O(1) |
| Pop count (Kernighan) | O(set bits) <= O(32) | O(1) |
| Reverse bits / scan all bits | O(32) = O(1) | O(1) |
| Counting Bits for 0..n | O(n) | O(n) output |
| Subset enumeration | O(2^n · n) | O(1) besides output |
Variations
- Cancellation by XOR - pairs vanish: Single Number, Missing Number.
- Partition by a differing bit - find the bit where two answers differ, then split: Single Number III.
- Per-bit counting - count each of the 32 bits modulo k when elements repeat k times (Single Number II).
- Bit DP - reuse the answer for
i >> 1ori & (i - 1): Counting Bits. - Common prefix - shift both ends right until equal, then shift back: Bitwise AND of Numbers Range.
- Carry simulation - XOR plus shifted AND: Sum of Two Integers.
- Bitmask as a set - visited states in BFS or DP over subsets (e.g. travelling-salesman-style DP).
Common mistakes
Java has no unsigned int. Using >> on a negative number copies the sign bit forever, so a "while (n != 0) n >>= 1" loop never ends. Use >>> for logical shifts, or loop a fixed 32 times.
- Operator precedence:
n & 1 == 0parses asn & (1 == 0)and does not compile in Java - always parenthesise(n & 1) == 0. - Writing
1 << 31or1 << 32and expecting a positive or 64-bit result; use1L << kfor longs. - Treating
n & (n - 1) == 0as "power of two" without also checkingn > 0(0 andInteger.MIN_VALUEslip through). - Forgetting that
~xequals-x - 1, so~is not "negative x". - Reaching for bit tricks when a plain hash set is clearer and space is not constrained - mention both and let the interviewer choose.
All practice problems
8 problems on this site use this pattern, easiest first. Solve them in order and say the instinct out loud before you code.