Pattern 18 of 20
Bit Manipulation
Use XOR, masks and shifts to count, toggle and cancel out bits.
When to use it
- Find the element that appears an odd number of times
- Count set bits, or test and flip individual bits
- Represent a small set as an integer mask
The idea
XOR cancels equal values, AND with a mask isolates bits, and n & (n − 1) clears the lowest set bit. These identities replace extra memory with a few integer operations.
Typical cost O(n) or O(number of bits) time, O(1) space.
How it works
Bit manipulation treats an integer as a row of switches. A handful of operations do most of the work: AND to test or clear bits, OR to set them, XOR to toggle, and shifts to move between positions. Each runs in constant time on the whole word.
XOR is the star. It is its own inverse (x ^ x = 0), and order does not matter, so XOR-ing a list where everything appears twice except one value leaves exactly that value. The same property finds a missing number when you XOR indices with values.
Two identities show up constantly: n & (n - 1) clears the lowest set bit, which lets you count set bits in as many steps as there are ones, and n & -n isolates the lowest set bit. A power of two is a positive n with n & (n - 1) equal to 0.
Bitmasks also encode small sets. With up to 20 items, every subset is an integer from 0 to 2^n - 1, which turns subset enumeration and DP over subsets into simple loops. In JavaScript remember that bitwise operators work on signed 32-bit integers.
How to attack it
- 1Look for pairs that cancel, parity, powers of two, or a small set that fits in a mask.
- 2Write down the identity you will rely on (x ^ x = 0, n & (n - 1), n & -n).
- 3Decide the word size and how negatives behave in your language.
- 4Loop over bits with shifts and masks rather than string conversions.
- 5Test with 0, 1, a negative value and the largest allowed value.
Template
A skeleton to adapt, not a solution to paste. Write it from memory a few times.
def single_number(nums):
# Every value appears twice except one: pairs cancel under XOR.
acc = 0
for x in nums:
acc ^= x
return acc
def count_set_bits(n):
count = 0
while n:
n &= n - 1 # clear the lowest set bit
count += 1
return count
def is_power_of_two(n):
return n > 0 and n & (n - 1) == 0
def all_subsets(items):
n = len(items)
out = []
for mask in range(1 << n): # each mask is one subset
out.append([items[i] for i in range(n) if mask >> i & 1])
return out
def bit_ops(x, i):
test = (x >> i) & 1
set_bit = x | (1 << i)
clear_bit = x & ~(1 << i)
toggle = x ^ (1 << i)
return test, set_bit, clear_bit, toggleVariants
- XOR cancellation
- Find the single value, the missing number, or two unique values (split the list by any bit where they differ).
- Counting bits
- Clear the lowest bit repeatedly, or build counts for 0..n with dp[i] = dp[i >> 1] + (i & 1).
- Bitmask subsets
- Enumerate every subset of up to about 20 items, or run DP where the state is a set of visited items.
- Bitwise addition
- Sum without +: XOR gives the sum without carries, AND shifted left gives the carries; repeat until no carry.
- Bit reversal and shifting
- Build the result one bit at a time, shifting it left while shifting the input right.
Pitfalls
- Operator precedence: in Python and JavaScript, == binds tighter than &, so wrap bitwise expressions in parentheses.
- Using >> instead of >>> in JavaScript when you need an unsigned shift.
- Infinite loops on negative numbers in Python, where integers have unbounded width; mask with & 0xFFFFFFFF.
- Assuming 1 << 31 is positive in JavaScript (it is negative).
- Using bitmasks for sets that are too large; 2^n blows up fast past about 20.
What it costs
| Operation | Cost |
|---|---|
| AND, OR, XOR, shifts | O(1) |
| Count set bits with n & (n - 1) | O(number of set bits) |
| XOR over a list | O(n) time, O(1) space |
| Enumerate all subsets | O(n · 2^n) |
25 Bit Manipulation problems
Easiest first. Problems marked Free can be solved without Pro.
- 1Lone Sensor ReadingFreeEasy
- 2Count the Lit SwitchesFreeEasy
- 3Bit Gap Between CodesFreeEasy
- 4Doubling Capacity CheckEasy
- 5Set-Bit Tally TableEasy
- 6Mirror a 32-Bit WordEasy
- 7Zigzag Binary PatternEasy
- 8Invert the Active BitsEasy
- 9Two Unpaired TicketsMedium
- 10Survivor of the TriplesMedium
- 11Adder Without ArithmeticMedium
- 12Shared Bits of a RangeMedium
- 13Every Feature-Flag ComboMedium
- 14Reflected Gray DialMedium
- 15Checksum Window QueriesMedium
- 16Fleet-Wide Bit DriftMedium
- 17No-Repeat Letter BannerMedium
- 18Disjoint Word-Pair ScoreMedium
- 19Balanced XOR SplitsMedium
- 20Nearest Code With Fixed OnesMedium
- 21Inspect Every RoomHard
- 22Cheapest Crew AssignmentHard
- 23Leanest Skill SquadHard
- 24Capped Semester PlannerHard
- 25Strongest XOR BlendHard
Solve them in the browser, in Python or JavaScript.