CMD Guide
HomeDSABit Manipulation

easy Number of 1 Bits

Number of 1 Bits (Hamming Weight)

Given a 32-bit integer n, return how many of its bits are set to 1. This count is the Hamming weight, or the population count (“popcount”). For n = 11, whose binary is 1011, the answer is 3.

It looks trivial — and it is, until the interviewer asks “can you do better than looking at all 32 bits?” The interesting content here is not the loop; it is why the clever loop is allowed to skip the zero bits, and whether “clever” is even the right call.

The naive baseline — inspect all 32 positions

The mechanical solution walks every bit position i from 0 to 31, shifts bit i down to position 0, and masks it: (n >> i) & 1. Sum those and you have the count.

int count = 0;
for (int i = 0; i < 32; i++) {
    count += (n >> i) & 1;   // isolate bit i, add 0 or 1
}

This always performs exactly 32 iterations, regardless of the input. For a fixed 32-bit word that is O(1) — but it is a constant 32, and it does the same work on n = 0 (no bits set) as on n = -1 (all 32 set). Note that (n >> i) & 1 is safe even when n is negative: an arithmetic right shift copies the sign bit into the top, but we only ever read the bottom bit after masking, so the sign fill never reaches us.

The bit insight — Kernighan skips the zeros

The key identity is n & (n - 1) clears the lowest set bit of n, and nothing else. Prove it by looking at what borrow does. Say the lowest set bit of n sits at position k, so n ends in 1 followed by k zeros: ...1​000. Subtracting 1 must borrow through those k trailing zeros, turning them into 1s, and it flips the bit at position k from 1 to 0: n - 1 = ...0​111. Now AND them, column by column:

So one n &= n - 1 removes exactly one set bit. Repeat until n becomes 0, and the number of iterations is the number of set bits. Brian Kernighan popularized this; it never visits a zero bit at all.

Traced example — n = 11 (binary 1011)

Itern (binary)n - 1 (binary)n & (n-1)count after
11011 (11)1010 (10)1010 (10)1
21010 (10)1001 (9)1000 (8)2
31000 (8)0111 (7)0000 (0)3
0000 (0)loop test n != 0 fails, stop3

Three iterations for three set bits — the naive loop would have taken 32. Each step visibly erases one 1: bit 0, then bit 1, then bit 3.

Java: Kernighan popcount

public class Solution {
    // Loops once per set bit, not once per bit position.
    public int hammingWeight(int n) {
        int count = 0;
        while (n != 0) {
            n &= (n - 1);   // erase the lowest set bit
            count++;
        }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(new Solution().hammingWeight(11));  // 3
        System.out.println(new Solution().hammingWeight(0));   // 0
        System.out.println(new Solution().hammingWeight(-1));  // 32  (0xFFFFFFFF)
        System.out.println(Integer.bitCount(11));              // 3  (the JDK builtin)
    }
}

Go: Kernighan popcount

package main

import (
	"fmt"
	"math/bits"
)

// n is unsigned: shifts are logical and there is no sign bit to worry about.
func hammingWeight(n uint32) int {
	count := 0
	for n != 0 {
		n &= n - 1 // erase the lowest set bit
		count++
	}
	return count
}

func main() {
	fmt.Println(hammingWeight(11))              // 3
	fmt.Println(hammingWeight(0))               // 0
	fmt.Println(hammingWeight(0xFFFFFFFF))      // 32
	fmt.Println(bits.OnesCount32(11))           // 3  (the stdlib builtin)
}

Why the Java version needs no >>>

Signed right shift is the classic trap in this problem — but the Kernighan loop sidesteps it. A naive while (n != 0) n >>= 1; in Java would never terminate on a negative n, because arithmetic >> keeps shifting in copies of the sign bit, so -1 stays -1 forever. You would have to write n >>>= 1 (the unsigned/logical shift) to feed zeros in from the top. Kernighan avoids the issue entirely: n &= n - 1 strictly removes set bits, so even -1 (all 32 bits set) reaches 0 in exactly 32 steps. Go has no >>> operator at all; it encodes signedness in the type, so we take a uint32 and its >> is already logical.

Complexity

Judgment layer — which one, and when

Edge cases & traps

Takeaways

🧩 Pattern · Bit Manipulation

Recognize it: Presence / pairing / parity with XOR and masks → think in bits.

→ more Bit Manipulation problems, grouped
🤖 Don't fully get this? Learn it with Claude

Stuck on Number of 1 Bits? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Number of 1 Bits** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Number of 1 Bits** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Number of 1 Bits**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Number of 1 Bits**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes