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]
给定一个数字num,求在0 ≤ i ≤ num范围内的所有数字i的二进制表示中1的个数。
思路一:动态规划
- 如果一个数字是2的k次幂,那它的二进制表示中肯定只有1个1
- 如果一个数字不是2的k次幂,那它肯定可以表示为较小的一个2的k次幂和另外一个数之和。
用公式表示就是:
C
(
i
)
=
{
1
i
是
2
的
k
次
幂
C
(
m
)
+
C
(
n
)
i
不
是
2
的
k
次
幂
C(i)= \begin{cases} 1 & i是2的k次幂\\ C(m)+C(n) & i不是2的k次幂 \end{cases}
C(i)={1C(m)+C(n)i是2的k次幂i不是2的k次幂
class Solution:
def isPower(self,n):
if n < 1:
return 0
i = 1
while i <= n:
if i == n:
# 如果等于n,表示是2的k次幂,返回原始值
return n
# 如果大于n,表示不是2的k次幂,返回原始值的后面一个2的k次幂
i <<= 1
return i
def countBits(self, num: int) -> List[int]:
res = []
for i in range(num+1):
if (i == 0):
res.append(0)
elif (i == 1):
res.append(1)
elif (self.isPower(i) != i):
lastPower = self.isPower(i)>>1
lastPowerCount = res[lastPower]
remain = i - lastPower
remainCount = res[remain]
res.append(lastPowerCount+remainCount)
else:
res.append(1)
return res
然后因为求2的k次幂时间复杂度较高,进一步考虑是否优化。比如对于6(110),它的二进制中的1的个数其实是和3(11)一样的,因为6是3左移以为,右边末尾补零得到的。所以很显然会得到: C ( i ) = C ( i > > 1 ) + i % 2 C(i) = C(i>>1) + i\%2 C(i)=C(i>>1)+i%2,也就是一个数 i 的二进制中的1的个数等于它除以2得到的数二进制中1的个数和除以2余数二进制中1的个数相加。
class Solution:
def countBits(self, num: int) -> List[int]:
res = [0]
for i in range(1,num+1):
res.append(res[i>>1]+i%2)
return res
思路二:Python 内置函数 bin
使用内置函数 bin
将一个数转化为二进制,再统计1的个数。
class Solution:
def countBits(self, num: int) -> List[int]:
target = []
for i in range(num+1):
count = bin(i).count('1')
target.append(count)
return target
THE END.