Bit Manipulation — Complete Guide

Sanjeev SharmaSanjeev Sharma
5 min read

Advertisement

Why Bit Manipulation?

Bitwise operations work directly on binary representations, enabling O(1) tricks that would otherwise need loops or extra space.


Essential Bit Operations

OperationExpressionMeaning
Check bit i(n >> i) & 1Is bit i set?
Set bit in | (1 << i)Set bit i to 1
Clear bit in & ~(1 << i)Set bit i to 0
Toggle bit in ^ (1 << i)Flip bit i
Remove last set bitn & (n-1)Clear rightmost 1
Isolate last set bitn & (-n)Keep only rightmost 1
Check power of 2n > 0 and (n & (n-1)) == 0
Count set bitsbin(n).count('1') or __builtin_popcount(n)
XOR self = 0n ^ n = 0Cancel duplicates
XOR with 0n ^ 0 = nIdentity

The 7 Core Patterns

Pattern 1 — XOR for Duplicate Cancellation

XOR of a number with itself = 0. Use to find single/missing numbers.

# Find single number (all others appear twice)
result = 0
for n in nums: result ^= n

Pattern 2 — Brian Kernighan (Count Set Bits)

n & (n-1) removes the lowest set bit. Count iterations.

count = 0
while n: n &= n-1; count += 1

Pattern 3 — Bitmask DP (Subsets as State)

State = bitmask of items selected. Iterate over all 2^n masks.

for mask in range(1 << n):
    for i in range(n):
        if mask & (1 << i):
            # item i is in this subset

Pattern 4 — Bitmask Enumeration (Subsets of a Mask)

Enumerate all subsets of a bitmask in O(2^popcount) using sub = (sub-1) & mask.

sub = mask
while sub:
    process(sub)
    sub = (sub - 1) & mask

Pattern 5 — Two's Complement Tricks

Negative numbers in two's complement: -n = ~n + 1. n & (-n) isolates rightmost set bit.

Pattern 6 — Bit by Bit Construction

Build answer bit by bit. Often used with XOR prefix sums.

prefix_xor = 0
for n in nums:
    prefix_xor ^= n
    # query trie for max XOR with prefix_xor

Pattern 7 — Bit Reversal / Rotation

Reverse bits of a 32-bit integer.

result = 0
for _ in range(32):
    result = (result << 1) | (n & 1)
    n >>= 1

Language-specific Bit Operations

Python

n & m   # AND
n | m   # OR
n ^ m   # XOR
~n      # NOT (bitwise complement)
n << k  # left shift
n >> k  # right shift
bin(n).count('1')  # popcount

C/C++

n & m; n | m; n ^ m; ~n; n << k; n >> k;
__builtin_popcount(n);    // GCC popcount
__builtin_clz(n);         // count leading zeros
__builtin_ctz(n);         // count trailing zeros

Java

n & m; n | m; n ^ m; ~n; n << k; n >> k; n >>> k; // unsigned right shift
Integer.bitCount(n);
Integer.highestOneBit(n);
Integer.numberOfLeadingZeros(n);

JavaScript

n & m; n | m; n ^ m; ~n; n << k; n >> k; n >>> k;
// No built-in popcount; use:
n.toString(2).split('').filter(x=>x==='1').length

Problem Index

#ProblemPatternDifficulty
01Single Number IXOR cancelEasy
02Single Number IIBit counting 3-stateMedium
03Single Number III (two singles)XOR + partitionMedium
04Number of 1 Bits (Hamming Weight)Brian KernighanEasy
05Counting BitsDP with bitsEasy
06Reverse BitsBit-by-bitEasy
07Missing NumberXOR or mathEasy
08Find the DifferenceXOREasy
09Power of Twon & (n-1) == 0Easy
10Sum of Two Integers (no +)Bit additionMedium
11Maximum XOR of Two NumbersBinary TrieMedium
12SubsetsBitmask enumerateMedium
13Total Hamming DistanceBit position analysisMedium
14Bitwise AND of Numbers RangeCommon prefixMedium
15Divide Two IntegersBit shiftingMedium
16Minimum XOR Sum (Bitmask DP)Bitmask DPHard
17Partition to K Equal Sum SubsetsBitmask DPMedium
18Bit Manipulation Master RecapCheatsheet

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro