๐ข Bit Manipulation
One-line summary: Operate directly on bits โ XOR, AND, OR, shifts โ for elegant O(1) tricks that would otherwise require O(n) logic.
Diagramโ
๐ฏ Conceptโ
Computers store integers as sequences of bits (binary digits). Bit manipulation works on these bits directly using bitwise operators, letting you replace whole loops with single, blazingly fast CPU instructions.
flowchart LR
A["Decimal 5"] --> B["Binary 0101"]
C["Decimal 3"] --> D["Binary 0011"]
B --> E{"Bitwise Op"}
D --> E
E -->|"AND &"| F["0001 = 1"]
E -->|"OR |"| G["0111 = 7"]
E -->|"XOR ^"| H["0110 = 6"]
Core Operatorsโ
| Operation | Symbol | Example | Result | Rule |
|---|---|---|---|---|
| AND | & | 5 & 3 | 1 | 1 only if both bits are 1 |
| OR | | | 5 | 3 | 7 | 1 if either bit is 1 |
| XOR | ^ | 5 ^ 3 | 6 | 1 if bits differ |
| NOT | ~ | ~5 | -6 | flips every bit |
| Left shift | << | 5 << 1 | 10 | multiply by 2แต |
| Right shift | >> | 5 >> 1 | 2 | divide by 2แต (floor) |
Key XOR properties: a^a=0, a^0=a, commutative, associative. These make XOR the go-to tool for "find the odd one out" problems.
Essential Bit Tricks (Cheat Sheet)โ
| Goal | Expression |
|---|---|
Check if i-th bit is set | (n >> i) & 1 |
Set the i-th bit | n | (1 << i) |
Clear the i-th bit | n & ~(1 << i) |
Toggle the i-th bit | n ^ (1 << i) |
| Turn off lowest set bit | n & (n - 1) |
| Isolate lowest set bit | n & (-n) |
| Check power of two | n > 0 && (n & (n - 1)) === 0 |
| Multiply / divide by 2 | n << 1 / n >> 1 |
โก Time & Space Complexityโ
| Operation | Time | Space | Notes |
|---|---|---|---|
Single bitwise op (&, |, ^, <<, >>) | O(1) | O(1) | One CPU instruction |
| Count set bits (Brian Kernighan) | O(k) | O(1) | k = number of set bits |
| Count set bits (naive scan) | O(log n) | O(1) | Iterate over all bits |
| Iterate all subsets via bitmask | O(2โฟ) | O(1) | n = number of elements |
| Bitmask DP | O(2โฟ ยท n) | O(2โฟ) | Classic TSP-style problems |
Key Insight: Bit operations are constant time regardless of the value, which is why they turn many O(n) checks into O(1).
Common Patternsโ
Find Single Numberโ
const singleNumber = (nums) => nums.reduce((acc, n) => acc ^ n, 0);
Check Even/Oddโ
const isEven = (n) => (n & 1) === 0;
Count Set Bits (Brian Kernighan)โ
function countBits(n) {
let count = 0;
while (n > 0) {
n &= n - 1;
count++;
}
return count;
}
XOR Swapโ
let a = 5,
b = 3;
a ^= b;
b ^= a;
a ^= b;
Power of Two Checkโ
const isPowerOfTwo = (n) => n > 0 && (n & (n - 1)) === 0;
Pitfallsโ
- JS bitwise ops work on 32-bit signed integers โ large numbers get truncated
~n = -(n+1)โ use>>> 0to convert to unsigned if needed- XOR swap doesn't work if
aandbpoint to the same variable
๐งช Worked Examplesโ
Example 1: Missing Number (XOR)โ
Given
ndistinct numbers in range[0, n], find the one missing.
function missingNumber(nums) {
let xor = nums.length; // start with n
for (let i = 0; i < nums.length; i++) {
xor ^= i ^ nums[i]; // cancel indices with values
}
return xor;
}
// Every present number cancels with its index; the missing one survives.
// Time: O(n), Space: O(1)
Example 2: Generate All Subsets (Bitmask)โ
Enumerate the power set of an array of size
nusing bit masks.
function subsets(nums) {
const n = nums.length;
const result = [];
for (let mask = 0; mask < 1 << n; mask++) {
const subset = [];
for (let i = 0; i < n; i++) {
if (mask & (1 << i)) subset.push(nums[i]);
}
result.push(subset);
}
return result;
}
// Each of the 2^n masks encodes one subset (bit i => include nums[i]).
// Time: O(2^n * n), Space: O(1) extra (excluding output)
Example 3: Sum of Two Integers Without +โ
Add two integers using only bitwise operations.
function getSum(a, b) {
while (b !== 0) {
const carry = (a & b) << 1; // bits that carry over
a = a ^ b; // add without carry
b = carry; // apply carry next round
}
return a;
}
// XOR adds bit-by-bit; AND<<1 computes the carry. Repeat until no carry.
// Time: O(1) (fixed 32-bit width), Space: O(1)
Practice Problemsโ
Easy Problemsโ
Medium Problemsโ
Hard Problemsโ
Related Topicsโ
- Math โ modular arithmetic and number theory
- School Basics โ XOR swap covered there
- Dynamic Programming โ bitmask DP for subset/state problems
- Recursion โ subset generation via recursion vs bitmask
โ Back to Home ยท ยฉ sparshjaswal