191. Number of 1 Bits - Explanation

Problem Link

Description

You are given an unsigned integer n. Return the number of 1 bits in its binary representation.

You may assume n is a non-negative integer which fits within 32-bits.

Example 1:

Input: n = 00000000000000000000000000010111

Output: 4

Example 2:

Input: n = 01111111111111111111111111111101

Output: 30


Recommended Time & Space Complexity

You should aim for a solution with O(1) time and O(1) space.


Hint 1

The given integer is a 32-bit integer. Can you think of using bitwise operators to iterate through its bits? Maybe you should consider iterating 32 times.


Hint 2

We iterate 32 times (0 to 31) using index i. The expression (1 << i) creates a bitmask with a set bit at the i-th position. How can you check whether the i-th bit is set in the given number? Maybe you should consider using the bitwise-AND ("&").


Hint 3

Since the mask has a set bit at the i-th position and all 0s elsewhere, we can perform a bitwise-AND with n. If n has a set bit at the i-th position, the result is positive; otherwise, it is 0. We increment the global count if the result is positive and return it after the iteration.


Company Tags

Please upgrade to NeetCode Pro to view company tags.



1. Bit Mask - I

Intuition

We are asked to count how many 1 bits are present in the binary representation of an integer n.
This value is also known as the Hamming Weight or population count.

A straightforward way to do this is to:

  • check each bit position one by one
  • see whether that bit is set (1) or not (0)

Since integers are typically represented using 32 bits, we can safely check all 32 bit positions.

At each position:

  • create a mask with a single 1 at that position using 1 << i
  • use bitwise AND (&) to test whether that bit is set in n

Algorithm

  1. Initialize a counter res = 0.
  2. For each bit position i from 0 to 31:
  3. Create a mask with only the i-th bit set:
    • mask = 1 << i
  4. Check if this bit is set in n:
    • If (mask & n) != 0, increment res
  5. After checking all 32 bits, return res.
class Solution:
    def hammingWeight(self, n: int) -> int:
        res = 0
        for i in range(32):
            if (1 << i) & n:
                res += 1
        return res

Time & Space Complexity

  • Time complexity: O(1)O(1)
  • Space complexity: O(1)O(1)

2. Bit Mask - II

Intuition

We want to count the number of 1 bits in the binary representation of an integer n.

Instead of checking every bit position explicitly, we can:

  • look at the least significant bit of n
  • then shift the number right to bring the next bit into that position

At each step:

  • n & 1 tells us whether the current least significant bit is 1
  • shifting n right by one (n >>= 1) moves us to the next bit

We repeat this until n becomes 0.

Algorithm

  1. Initialize a counter res = 0.
  2. While n > 0:
    • If the least significant bit is 1 (n & 1):
      • increment res
    • Shift n one bit to the right (n >>= 1)
  3. When n becomes 0, all bits have been processed.
  4. Return res.
class Solution:
    def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            res += 1 if n & 1 else 0
            n >>= 1
        return res

Time & Space Complexity

  • Time complexity: O(1)O(1)
  • Space complexity: O(1)O(1)

3. Bit Mask (Optimal)

Intuition

We want to count the number of 1 bits in the binary representation of an integer n (Hamming Weight).

A very efficient trick comes from this key observation:

  • Subtracting 1 from a number flips the rightmost 1 bit to 0 and turns all bits to its right into 1
  • Performing n & (n - 1) removes the rightmost 1 bit from n

So every time we do:
n = n & (n - 1) we eliminate exactly one 1 bit.

This means:

  • the number of iterations equals the number of 1 bits
  • we don’t waste time checking bits that are 0

That’s why this approach is considered optimal.

Algorithm

  1. Initialize a counter res = 0.
  2. While n is not zero:
    • Update n = n & (n - 1) to remove the rightmost 1 bit
    • Increment res by 1
  3. When n becomes 0, all 1 bits have been removed.
  4. Return res.
class Solution:
    def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            n &= n - 1
            res += 1
        return res

Time & Space Complexity

  • Time complexity: O(1)O(1)
  • Space complexity: O(1)O(1)

4. Built-In Function

Intuition

We want to find the Hamming Weight of a number, which means counting how many 1 bits are present in its binary representation.

Most programming languages provide:

  • a way to convert a number into binary form, or
  • a built-in utility to count set bits

Instead of manually checking each bit using bit manipulation, we can rely on these built-in features. This makes the solution short, easy to understand, and less error-prone, especially for beginners.

This approach focuses on clarity and simplicity, not on low-level optimizations.

Algorithm

  1. Convert the given number n into its binary representation
    (using a built-in binary conversion or bit-count utility provided by the language).
  2. Count the number of 1 bits in that representation.
  3. Return the count.
class Solution:
    def hammingWeight(self, n: int) -> int:
        return bin(n).count('1')

Time & Space Complexity

  • Time complexity: O(1)O(1)
  • Space complexity: O(1)O(1)

Common Pitfalls

Signed vs Unsigned Integer Handling

In some languages, right-shifting a signed negative integer fills with 1s (arithmetic shift) instead of 0s (logical shift). This can cause infinite loops when using while (n != 0) with negative inputs. Use unsigned types or the >>> operator in languages that support it.

Using Division Instead of Bit Shift

While n / 2 and n >> 1 produce the same result for positive integers, division can behave differently for negative numbers and is generally slower. Stick to bitwise operations for clarity and consistency with the problem's intent.