LeetCode Problem Workspace

Counting Bits

Compute the number of 1 bits for every integer from 0 to n using state transition dynamic programming for efficiency.

category

2

Topics

code_blocks

5

Code langs

hub

3

Related

Practice Focus

Easy · State transition dynamic programming

bolt

Answer-first summary

Compute the number of 1 bits for every integer from 0 to n using state transition dynamic programming for efficiency.

Interview AiBox logo

Ace coding interviews with Interview AiBox guidance for State transition dynamic programming

Try AiBox Copilotarrow_forward

This problem can be solved by recognizing that the number of 1s in i can be derived from previously computed results using state transition rules. By leveraging dynamic programming and bit manipulation, we can build the solution incrementally without recalculating from scratch. The key insight is using i & (i - 1) to reduce i to a smaller subproblem whose result is already known.

Problem Statement

Given a non-negative integer n, return an array ans of length n + 1 where ans[i] represents the number of 1's in the binary representation of integer i. This requires efficiently computing counts without converting each number manually, leveraging previously computed results.

For example, with n = 5, the output should be [0,1,1,2,1,2], representing the counts for integers 0 through 5. Constraints are 0 <= n <= 105, ensuring solutions must handle large n efficiently.

Examples

Example 1

Input: n = 2

Output: [0,1,1]

0 --> 0 1 --> 1 2 --> 10

Example 2

Input: n = 5

Output: [0,1,1,2,1,2]

0 --> 0 1 --> 1 2 --> 10 3 --> 11 4 --> 100 5 --> 101

Constraints

  • 0 <= n <= 105

Solution Approach

Dynamic Programming with State Transition

Initialize an array dp of size n + 1 with dp[0] = 0. For each i from 1 to n, compute dp[i] = dp[i & (i - 1)] + 1. This uses the fact that removing the lowest set bit of i gives a number whose bit count is already known.

Bit Manipulation Insight

Recognize that i & (i - 1) clears the lowest set bit, allowing the number of 1s in i to be derived from a smaller number. This avoids recomputation and directly links the solution to the problem's pattern of state transition DP.

Iterative Construction

Iterate from 1 to n and fill dp array using the state transition formula. This guarantees O(n) time complexity and O(n) space, scaling efficiently even for large n while maintaining correctness.

Complexity Analysis

Metric Value
Time Depends on the final approach
Space Depends on the final approach

Time complexity is O(n) because each dp[i] is computed in constant time using previously computed values. Space complexity is O(n) for the dp array storing counts for 0 through n.

What Interviewers Usually Probe

  • Expect recognition of the state transition pattern for efficient DP.
  • Look for correct use of i & (i - 1) for bit manipulation optimization.
  • Check if candidate avoids naive per-number bit counting loops.

Common Pitfalls or Variants

Common pitfalls

  • Recomputing bit counts for each i instead of using DP, leading to O(n log n) time.
  • Forgetting to initialize dp[0], causing index errors or incorrect base cases.
  • Misusing i & (i - 1) logic, resulting in off-by-one errors in counts.

Follow-up variants

  • Compute the number of 0 bits instead of 1 bits in each number from 0 to n.
  • Return bit counts only for odd numbers up to n.
  • Calculate bit counts for numbers in a given range [a, b] using the same DP approach.

FAQ

What is the best approach to solve the Counting Bits problem efficiently?

Use dynamic programming with the state transition formula dp[i] = dp[i & (i - 1)] + 1 to leverage previously computed results.

Why does i & (i - 1) help in counting bits?

It clears the lowest set bit, allowing dp[i] to build directly on the count of a smaller subproblem.

Can this method handle large n values like 100,000?

Yes, because the DP approach computes each dp[i] in constant time, achieving O(n) overall time and space complexity.

Is converting each number to binary and counting 1s a good approach?

No, it is inefficient for large n and defeats the problem's pattern of using state transition DP for incremental computation.

Does this problem always require bit manipulation?

While bit manipulation simplifies the DP computation, understanding the state transition pattern is the key; other methods exist but are less efficient.

terminal

Solution

Solution 1

#### Python3

1
2
3
class Solution:
    def countBits(self, n: int) -> List[int]:
        return [i.bit_count() for i in range(n + 1)]

Solution 2

#### Python3

1
2
3
class Solution:
    def countBits(self, n: int) -> List[int]:
        return [i.bit_count() for i in range(n + 1)]
Counting Bits Solution: State transition dynamic programming | LeetCode #338 Easy