LeetCode 191 · Easy · Bit Manipulation

Number of 1 Bits

Given a positive integer n, return how many 1s its binary representation has (its Hamming weight).

O(k)time · k = number of 1s
O(1)space
n & (n − 1)clears the lowest 1

a whole number from 1 to 2147483647 (2³¹ − 1) · shown in 8, 16 or 32 bits by size

n & (n − 1) subtracting 1 flips the lowest 1 and the zeros below it · AND keeps a bit only where both rows have 1

Cleared so far one loop round per 1 bit, the zeros cost nothing

public int hammingWeight(int n) { int res = 0; while (n != 0) { n &= n - 1; // drop the lowest 1 bit res++; } return res;}
n
—
n − 1
—
res
0

Why it works

  1. Brute force checks every bit: res += n & 1; n >>>= 1 32 times (or Integer.bitCount(n)). O(32) per call, even for a number with a single 1.
  2. n − 1 flips the lowest 1 and every 0 below it. Borrowing in binary turns …1000 into …0111, and leaves the higher bits alone. ANDing with n keeps the higher bits and zeroes the whole flipped tail, so exactly one 1 disappears per round.
  3. O(k) rounds for k ones, at most 31 for a 31-bit number, O(1) space. The loop jumps straight from one 1 to the next, skipping runs of zeros.
  4. Pitfall: the sign bit. A Java int is 32 bits and LeetCode passes the input as unsigned bits, so n can arrive negative. n &= n - 1 still reaches 0. The shifting version needs >>>: >> copies the sign bit and never reaches 0 for a negative n.
  5. Related: n & (n − 1) == 0 tests for a power of two (231). Counting Bits (338) reuses the same idea as a DP: bits[i] = bits[i & (i − 1)] + 1.