Intuition
Dropping the last bit of i gives i // 2, whose bit count we already computed. Add back the bit we dropped (i & 1).
Explanation
Key relation
The binary form of i >> 1 is i with its last bit removed. So the number of set bits in i equals the set bits in i >> 1 plus the last bit itself:
ans[i] = ans[i >> 1] + (i & 1)
Since i >> 1 < i, its answer is already filled — a clean bottom-up DP.
Walk-through
- Allocate
ansof lengthn + 1, withans[0] = 0. - For
ifrom1ton:ans[i] = ans[i >> 1] + (i & 1). - Return
ans.
Worked example (n = 5)
| i | binary | i>>1 | ans[i>>1] | i&1 | ans[i] |
|---|---|---|---|---|---|
| 0 | 000 | - | - | - | 0 |
| 1 | 001 | 0 | 0 | 1 | 1 |
| 2 | 010 | 1 | 1 | 0 | 1 |
| 3 | 011 | 1 | 1 | 1 | 2 |
| 4 | 100 | 2 | 1 | 0 | 1 |
| 5 | 101 | 2 | 1 | 1 | 2 |
Result: [0,1,1,2,1,2].
Complexity
- Time: O(n) — one O(1) transition per value.
- Space: O(1) extra (ignoring the output array).
Implementation
class Solution {
public int[] countBits(int n) {
int[] ans = new int[n + 1];
for (int i = 1; i <= n; i++) {
ans[i] = ans[i >> 1] + (i & 1);
}
return ans;
}
}