Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array.
Example 1:
Input: 2 Output: [0,1,1]
Example 2:
Input: 5
Output: [0,1,1,2,1,2]
Follow up:
The description was taken from https://leetcode.com/problems/counting-bits/.
#O(N) Time, O(N) Space
class Solution:
def countBits(self, num: int) -> List[int]:
dp = [0]*(num+1)
for i in range(1, num+1):
dp[i] = dp[i &(i-1)] + 1
return dp
In Number of 1 Bits, we went over a trick to count bits by continuously using an AND
operator on the number and the number minus one. This flips the least significant bit in the number to zero, so we just needed to count how many iterations it took to make the number zero.
Here, we will be doing a similar approach, but we will be saving the result for each subproblem from one to n
.
This way, we don't have to keep recalculating values.
We can solve this by creating a dp
array to cache previously calculated values and build upon those subproblem answers to get a bottom-up solution.
We will start by creating our dp
array.
This array will hold the answers to each subproblem.
dp = [0]*(num+1)
Then for each iteration, we will ask how many bits are in the binary number equal to the current index.
This would start from index one since there are zero bits in the number zero.
for i in range(1, num+1):
dp[i] = dp[i &(i-1)] + 1
The way we can calculate this is by referring to the answers to the previous subproblems for the previous indices.
For example, let's say we are trying to calculate how many bits are in the binary number three.
We would lookup in our dp
array how many bits were in the index number without the last set bit, get that answer in constant time and just add back the last bit, then we'd mark the index with that many bits. The calculation would look like this:
dp[3] = dp[3 &(3-1)] + 1
dp[3] = dp[0011 & 0010] + 1
dp[3] = dp[0010] + 1, dp[2] = 1
dp[3] = 1+1
dp[3] = 2
for i in range(1, num+1):
dp[i] = dp[i &(i-1)] + 1
Once we have finished calculating each binary value, we will return the dp
array.
return dp