Counting Bits
Bit count of every i in [0, n] in O(n) using dp[i] = dp[i >> 1] + (i & 1).
2 min read
dp bit-manipulation
Problem#
Return an array ans where ans[i] is the number of 1 bits in i, for i in [0, n].
Examples#
n = 5→[0,1,1,2,1,2]
Constraints#
0 <= n <= 10^5.
Approach#
DP: dp[i] = dp[i >> 1] + (i & 1). Halving strips the last bit; the dropped bit contributes 0 or 1.
Solution#
class Solution {public: vector<int> countBits(int n) { vector<int> dp(n + 1, 0); for (int i = 1; i <= n; ++i) dp[i] = dp[i >> 1] + (i & 1); return dp; }};func countBits(n int) []int { dp := make([]int, n+1) for i := 1; i <= n; i++ { dp[i] = dp[i>>1] + (i & 1) } return dp}from typing import List
class Solution: def countBits(self, n: int) -> List[int]: dp = [0] * (n + 1) for i in range(1, n + 1): dp[i] = dp[i >> 1] + (i & 1) return dpfunction countBits(n) { const dp = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) dp[i] = dp[i >> 1] + (i & 1); return dp;}class Solution { public int[] countBits(int n) { int[] dp = new int[n + 1]; for (int i = 1; i <= n; i++) dp[i] = dp[i >> 1] + (i & 1); return dp; }}function countBits(n: number): number[] { const dp: number[] = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) dp[i] = dp[i >> 1] + (i & 1); return dp;}Editorial#
Linear-time alternative to per-element popcount. The recurrence exploits binary structure: i = (i >> 1) shifted up + last bit.
Complexity#
- Time: O(n).
- Space: O(n).
Concept revision#
Related#