1011(11)
n
Count the 1-bits in a 32-bit integer using Brian Kernighan's trick: n & (n − 1) clears the lowest set bit in one operation, so the loop runs exactly as many times as there are set bits — far fewer iterations than checking all 32 positions.
Return the number of 1 bits (the Hamming weight / population count) in the binary representation of a non-negative integer. n = 11 is 1011 in binary, so the answer is 3. n = 128 is 10000000 — exactly one set bit — so the answer is 1.
n flips the lowest set bit to 0 and sets every trailing 0 to 1. AND-ing back with n zeroes out those trailing bits and preserves everything above. One iteration = one 1-bit removed. Count iterations to count bits — the loop runs exactly k times for an integer with k set bits.count = 0.n = n & (n − 1). This is the whole trick. One AND clears exactly one 1-bit, no matter which position it occupies.n = 0 the loop exits; count holds the answer.n & 1 to test the LSB, then n >>>= 1to right-shift — correct but always loops 32 times. Kernighan's trick loops only k times (k = set bits), which matters when k ≪ 32.Both are technically O(1) for a fixed-width integer, but Kernighan is faster in practice for sparse bit patterns. The built-in Math.clz32 / CPU popcnt instruction is the real-world constant-time answer.
n & (n − 1) idiom appears in Power of Two (exactly one bit set → n & (n − 1) === 0), Counting Bits (fill a DP table using it as a recurrence), Hamming Distance (XOR then count), and Reverse Bits.11 in binary: 1011. We use Brian Kernighan's trick: each n & (n − 1) clears the lowest set bit in one step.function hammingWeight(n: number): number {
let count = 0;
while (n !== 0) {
n = n & (n - 1); // clear the lowest set bit
count++;
}
return count;
}count accumulates one increment per set bit found. Initialise to 0 before the loop.n !== 0 exits as soon as all bits are cleared. For n = 0, the body never executes and we correctly return 0.n & (n - 1) clears the lowest set bit. Why? Subtracting 1 from n flips its LSB from 1 to 0 and sets all trailing zeros to 1. AND-ing with the original n zeroes those bits and leaves everything above the LSB intact. One operation, one bit gone.n === 0; return the tally. Contrast with the naive approach: while (n) {count += n & 1; n>>> = 1; } — it always executes 32 iterations.BigInt and adjust the !== 0n / n & (n - 1n) operations.n > 0 && (n & (n - 1)) === 0 is the classic O(1) test.bits[i] = bits[i >> 1] + (i & 1) — each entry derived in O(1) from a previously computed one.| "count set bits / 1-bits / popcount" | n & (n-1) loop, k iterations |
| "is n a power of two?" | n > 0 && (n & (n-1)) === 0 |
| "Hamming distance between a and b" | hammingWeight(a ^ b) |
| "fill bits[0..n] for all n" | DP: bits[i] = bits[i>>1] + (i & 1) |
let count = 0;
while (n !== 0) {
n = n & (n - 1); // clear lowest set bit
count++;
}
return count;n = 11 (binary 1011)?n & (n − 1) do?bits[0..n] in O(n) time. Which recurrence is correct?n = 0, what does hammingWeight return?