02
Bit counting / powers (Bit Manipulation Sub-pattern)
Questions about one number's bits: how many are set, whether exactly one is set, their reverse, or building a quotient from powers of two.
Signals in the problem statement
- ›
"number of 1 bits", "Hamming weight / distance"
- ›
"power of two / four"
- ›
"count bits for every number 0..n"
- ›
"reverse bits", "without multiplication or division"
What makes it different
Count / power → n & (n − 1). Counting for all of 0..n → DP: bits[i] = bits[i >> 1] + (i & 1). Reverse → exactly 32 shifts. Division → subtract the largest divisor · 2^k that fits, from the top bit down.
Questions
ordered from “learn the idea” to “recognise it without help”- 1Number of 1 BitsWalkthroughEasyBasic Anchor·LeetCode #191
- 2Power of TwoWalkthroughEasyBasic Reinforcement·LeetCode #231
- 3Counting BitsWalkthroughEasySlight Variation·LeetCode #338
- 4Reverse BitsWalkthroughEasyMedium·LeetCode #190
- 5Divide Two IntegersWalkthroughMediumPattern Transfer·LeetCode #29
Template
bit-tricks-template.cpp
// n & (n - 1) removes the lowest 1-bit: 1100 -> 1000.
int countOnes(unsigned n) {
int c = 0;
while (n) { n &= n - 1; c++; } // runs once per 1-bit
return c;
}
// A power of two has exactly one 1-bit. Check n > 0 first (0, negatives, INT_MIN).
bool isPowerOfTwo(int n) { return n > 0 && (n & (n - 1)) == 0; }
// x & -x keeps only the lowest 1-bit: 1100 -> 0100.
unsigned lowestBit(unsigned x) { return x & -x; }
// Read, set, clear, flip bit i (0 = rightmost). Use unsigned when i can be 31.
bool getBit(unsigned n, int i) { return (n >> i) & 1; }
unsigned setBit(unsigned n, int i) { return n | (1u << i); }
unsigned clearBit(unsigned n, int i) { return n & ~(1u << i); }
unsigned flipBit(unsigned n, int i) { return n ^ (1u << i); }
// Bits of every number 0..n: i without its last bit is i >> 1, already solved.
vector<int> countBitsUpTo(int n) {
vector<int> bits(n + 1, 0);
for (int i = 1; i <= n; i++) bits[i] = bits[i >> 1] + (i & 1);
return bits;
}
// Reverse all 32 bits: exactly 32 steps, so leading zeros become trailing zeros.
uint32_t reverse32(uint32_t n) {
uint32_t r = 0;
for (int i = 0; i < 32; i++) { r = (r << 1) | (n & 1); n >>= 1; }
return r;
}Remember this · Bit Manipulation
Trigger
"Every element appears twice except…", power of two, counting set bits, subsets as bitmasks, O(1) space tricks.
Think
What happens to this problem if I look at each bit separately?
Key question
Which bit operation (XOR, AND, OR, shift) cancels or isolates what I need?