The direct approach checks every one of the 32 bits. The clever trick uses the identity n & (n - 1), which clears the lowest set bit of n in a single operation — so the loop only runs once per set bit instead of once per bit position.
Check Every Bit
Time O(32) = O(1)Space O(1)Shift through all 32 bit positions and test each one with a mask.
class Solution: def hammingWeight(self, n: int) -> int: count = 0 for i in range(32): if n & (1 << i): count += 1 return countFor n = 11 (binary 00000000000000000000000000001011), the loop tests bit 0 (1, set), bit 1 (1, set), bit 2 (0, clear), bit 3 (1, set), then bits 4 through 31 are all 0. Three bits are set, so it returns 3.
Complexity: always exactly 32 iterations regardless of how many bits are actually set → O(1) time (bounded by the fixed integer width), O(1) space.
Brian Kernighan's Trick
OptimalTime O(k)Space O(1)n & (n - 1) always clears exactly the lowest set bit of n. Subtracting 1 flips every trailing zero to a 1 and the lowest set 1 to a 0; ANDing with the original n keeps all the higher bits untouched but zeroes out that lowest set bit. Repeating this until n becomes 0 counts each set bit exactly once, so the loop only runs k times where k is the number of set bits — never 32 regardless of how sparse the bits are.
class Solution: def hammingWeight(self, n: int) -> int: count = 0 while n: n &= n - 1 count += 1 return countWatch the borrow in n - 1 flip the lowest set bit and every trailing zero, then the AND with n clear exactly that bit.
Start with n = 11, binary 00001011. Each pass clears the lowest set bit, so the loop runs once per set 1.
Complexity: the loop body runs once per set bit, so it takes O(k) time where k <= 32 is the number of set bits — strictly fewer iterations than checking all 32 positions whenever n is sparse. Still O(1) space.
Follow-up (called many times): precompute the Hamming weight of every byte (0–255) once into a 256-entry lookup table, then split n into four bytes and sum four table lookups. This amortizes the counting work across calls, turning each subsequent call into four O(1) array reads instead of a bit-by-bit loop.