Last Updated: March 20, 2026
We're given a positive integer and need to count how many bits in its binary form are 1. For instance, the number 11 in binary is 1011, so the answer is 3.
This is a classic bit manipulation problem. The straightforward way is to check each bit one by one, but there's a clever trick using n & (n - 1) that lets us skip over the zero bits entirely. And if this function gets called millions of times, we can precompute results in a lookup table for constant-time answers.
1 <= n <= 2^31 - 1 → The input is a 32-bit positive integer. This means we have at most 31 bits to inspect, so even a bit-by-bit scan is effectively O(1). The optimization question here isn't about asymptotic complexity, it's about reducing the constant factor.The most natural way to count set bits: look at each bit position one at a time. We can check the least significant bit using n & 1 (which is 1 if the bit is set, 0 otherwise), then right-shift n to move the next bit into position. Repeat until all bits are processed.
Since n is at most 31 bits, this loop runs at most 31 times. Simple and effective.
count to 0.n is greater than 0:n & 1 equals 1, increment count.n by 1.count.The loop always runs up to 31 times, even if only 1 bit is set. What if we could skip straight to the set bits and ignore all the zeros in between?
Here's the key trick: n & (n - 1) clears the lowest set bit of n. Why? When you subtract 1 from a number, it flips the lowest set bit to 0 and all the bits below it to 1. When you AND the original number with this result, the lowest set bit disappears, and everything below it becomes 0.
So instead of checking every bit position, we just keep clearing the lowest set bit until n becomes 0. The number of times we do this equals the number of set bits. If a number has only 2 set bits out of 31, we loop just twice.
When you subtract 1 from a binary number, the rightmost 1 becomes 0, and all the 0s to its right become 1s. For example, 1010 - 1 = 1001. The AND operation between n and n-1 keeps everything above the rightmost set bit unchanged and zeros out the rightmost set bit along with everything below it. This is why each iteration eliminates exactly one set bit.
count to 0.n is greater than 0:n = n & (n - 1).count.count.Brian Kernighan's is great for a single call, but what if hammingWeight is called millions of times in a hot loop? Each call still requires a loop. What if we precomputed the bit count for every possible input chunk and turned the problem into a series of lookups?
This approach directly answers the follow-up question. We precompute the number of set bits for every possible byte value (0 to 255) and store them in a table. Then for any 32-bit integer, we split it into 4 bytes and sum up 4 table lookups. Each lookup is O(1), so the entire operation is O(1) with no loops at all.
The trade-off is 256 entries of precomputed data, which is trivial in terms of memory but makes each call blazing fast.
table[i] stores the number of set bits in i.n, extract each of its 4 bytes using bit masking and shifting.