Counting Bits easy
Problem Statement
Given an integer n
, return an array ans
of length n + 1
such that for each i
(0 <= i <= n), ans[i]
is the number of 1's in the binary representation of i
.
Example 1:
Input: n = 2 Output: [0,1,1] Explanation: 0 --> 0 1 --> 1 2 --> 10
Example 2:
Input: n = 5 Output: [0,1,1,2,1,2] Explanation: 0 --> 0 1 --> 1 2 --> 10 3 --> 11 4 --> 100 5 --> 101
Steps and Explanation
The most straightforward approach involves iterating through each number from 0 to n
, converting it to its binary representation, and counting the number of 1s. However, this approach can be inefficient for larger values of n
. A more efficient approach leverages the following observation:
The number of 1s in the binary representation of a number i
is related to the number of 1s in the binary representation of i/2
(integer division). Specifically:
- If
i
is even, the number of 1s ini
is the same as the number of 1s ini/2
. - If
i
is odd, the number of 1s ini
is one more than the number of 1s ini/2
.
We can use dynamic programming to efficiently compute the number of 1s for each number. We create an array dp
where dp[i]
stores the number of 1s in the binary representation of i
. We initialize dp[0] = 0
. Then, for each i
from 1 to n
, we compute dp[i]
based on the value of dp[i/2]
according to the rules above.
Code
class Solution {
public:
vector<int> countBits(int n) {
vector<int> dp(n + 1);
dp[0] = 0;
for (int i = 1; i <= n; ++i) {
if (i % 2 == 0) {
dp[i] = dp[i / 2];
} else {
dp[i] = dp[i / 2] + 1;
}
}
return dp;
}
};
Complexity Analysis
- Time Complexity: O(n). We iterate through the numbers from 0 to n once.
- Space Complexity: O(n). We use an array
dp
of sizen+1
to store the results. This is unavoidable since we need to return an array of size n+1.