Bit Manipulation Tricks & Bitmasks
Quick Overview
XOR cancels a value against itself, so `1 ^ 1 = 0`. That one property isolates the single unpaired number in an array using `O(1)` space and no hash map at all.
Deep Dive
1. Operating at the Silicon Bit Level
All computer data is stored in binary bits (0 and 1). Bit Manipulation applies bitwise logic directly on integer bits in O(1) instant execution time with zero memory overhead.
2. Core Bitwise Operators
| Operator | Name | Logic Rule |
|---|---|---|
a & b | AND | 1 only if both bits are 1 |
| **`a | b`** | OR |
a ^ b | XOR | 1 if bits are different (1 ⊕ 0 = 1, 1 ⊕ 1 = 0) |
~a | NOT | Inverts all bits |
a << k | Left Shift | Multiplies by 2^k (5 << 1 == 10) |
a >> k | Right Shift | Divides by 2^k (10 >> 1 == 5) |
3. High-Value Bit Manipulation Tricks
// Trick 1: Check if Number is Power of Two in O(1)
function isPowerOfTwo(n) {
return n > 0 && (n & (n - 1)) === 0;
}
console.log(isPowerOfTwo(16)); // Output: true (16 is 10000_2, 15 is 01111_2 -> 16 & 15 == 0)
console.log(isPowerOfTwo(18)); // Output: false
// Trick 2: Find the Single Non-Duplicate Number using XOR
// Rule: x ^ x = 0 and x ^ 0 = x (Duplicates cancel out!)
function singleNumber(nums) {
let result = 0;
for (const num of nums) {
result ^= num;
}
return result;
}
console.log(singleNumber([4, 1, 2, 1, 2])); // Output: 4 (1^1=0, 2^2=0 -> 4 remains)
// Trick 3: Count Set Bits (Hamming Weight / Brian Kernighan's Algorithm)
function countSetBits(n) {
let count = 0;
while (n > 0) {
n &= (n - 1); // Clears the lowest set bit in O(1)
count++;
}
return count;
}
console.log(countSetBits(11)); // Output: 3 (11 is 1011_2 in binary)
4. Bitmasks for State Representation
An integer can represent a set of up to 32 boolean flags:
- Set bit
i:mask |= (1 << i) - Clear bit
i:mask &= ~(1 << i) - Check bit
i:(mask & (1 << i)) !== 0
5. Common Mistakes
- Operator Precedence Pitfall: In JavaScript, equality operators have higher precedence than bitwise operators! Writing
n & 1 === 0is evaluated asn & (1 === 0)! Always wrap bitwise operations in parentheses:(n & 1) === 0.
6. Congratulations!
Congratulations! You have completed all 30 foundational Data Structures & Algorithms Core Patterns Learning Bytes, mastering everything from Big O analysis, sliding windows, and linked lists to binary search trees, Dijkstra's algorithm, dynamic programming, and bit manipulation!
How was this byte?
Learning Progress
30 of 30Next Up in Data Structures & Algorithms Core Patterns
Big O Notation: Time & Space Complexity
Big O describes how work grows, not how long it takes. An `O(N^2)` algorithm on 1,000 items does a million steps; the same work at `O(N log N)` does about 10,000.
Dynamic Arrays & Amortized Resizing
A dynamic array doubles rather than growing by one, so the expensive copy lands on the 1st, 2nd, 4th and 8th push. Averaged across every push, that is `O(1)` amortised.
Two Pointers Pattern (Converging & Symmetrical)
A nested loop tests every pair in `O(N^2)`. On sorted data, moving two pointers inward from both ends rules out half the remaining candidates at each step and settles it in one `O(N)` pass.