Topic links
https://leetcode.com/problems/counting-bits/
Original title
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:
for num = 5
should return [0,1,1,2,1,2]
.
Follow up:
- It is very easy-to-come up with a solution with Run time O (n*sizeof (integer)). But can do it in linear time O (n)/possibly in a single pass?
- Space complexity should be O (n).
- Can do it like a boss? Do it without using any builtin function like __builtin_popcount in C + + or in any other language.
Hint:
- should make use of the what you have produced already.
- Divide The numbers in ranges like [2-3], [4-7], [8-15] and so on. and try to generate the new range from previous.
- Or does the Odd/even status of the the number help you in calculating the number of 1s?
Method of Thinking
The topic gives the hint, can be convenient for us to think, but in any case, it is best to first several numbers of the binary written to observe. such as the first 10 numbers:
01101110010111011110001001......
The key of this problem is to find the law, the essence is a dynamic planning problem. There are many ways to get new data using existing data.
Idea one
The most violent idea, count the number of binary inside the number of 1. Although this practice can be AC, but does not meet the "follow up" requirements, the efficiency is also low, for reference only.
Code
class Solution(object): def countBits(self, num): """ :type num: int :rtype: List[int] """ res = [] forin1): res.append(bin(i).count(‘1‘)) return res
Idea two
By observing the binary of the first 10 numbers, it can be found that: [2-3] The number of 1 is [0-1] the number of the corresponding plus one; [4-7] is [0-3] corresponding plus one; [8-15] is [0-7] corresponds to plus one; In essence, the highest bit of 1 becomes 0 to get the corresponding smaller number.
Code One
class solution(object): def countbits(self, num): "" : Type Num:int:rtype:list[int] "" "DP = [0] I =0 while True: forJinchXrange1<<i,1<< (i+1)):ifJ > Num:returnDP Dp.append (1+ Dp[j-(1<<i)]) i + =1 returnDp
Description
Based on the above ideas, you can solve the problem through the Python list extend operation, but will waste some space. The code is as follows:
Code two
class Solution(object): def countBits(self, num): """ :type num: int :rtype: List[int] """ dp = [01] while len(dp) <= num: dp.extend(map(lambda x:x+1, dp)) return dp[:num+1]
Three Ideas
The idea is to remove the top 1 of a number to get a smaller number, then you can also remove the lowest bit of 1 to get a smaller number, so there is the formula:
Dp[i] = dp[i& (i-1)] + 1
Code
class Solution(object): def countBits(self, num): """ :type num: int :rtype: List[int] """ dp = [0] forin xrange(11): dp.append(dp[i & (i-11) return dp
Idea four
In addition, you can consider the parity, the current number to the right one bit, if the current number is odd then the number of 1 is the same, otherwise the number of 1 plus one, the formula is as follows:
Dp[i] = dp[i>>1] + (i&1)
Code
class solution (object) : def countbits : dp = [0 ] for i in xrange (1 , num + 1 ): Dp.append (dp[i >> 1 ] + (I &
1
)) return dp
PS: Write wrong or write not clear please help point out, thank you!
Reprint Please specify: http://blog.csdn.net/coder_orz/article/details/52063216
338. Counting Bits [Medium] (Python)