题解
本题主要考察二进制的自身特性。
二进制的两个特性:
- 奇数的二进制中1的个数=它上一位偶数的二进制中1的个数+1
如: ( 3 ) 10 = ( 11 ) 2 , ( 2 ) 10 = ( 10 ) 2 (3)_{10}=(11)_{2},(2)_{10}=(10)_{2} (3)10=(11)2,(2)10=(10)2
( 13 ) 10 = ( 1101 ) 2 , ( 12 ) 10 = ( 1100 ) 2 (13)_{10}=(1101)_{2},(12)_{10}=(1100)_{2} (13)10=(1101)2,(12)10=(1100)2 - 偶数中二进制1的个数等于这个偶数除以2后的数二进制1的个数。
解释:位运算 < < << <<,表示将当前数乘以2,即在二进制的最右侧加个0。
如: ( 10 ) 10 = ( 1010 ) 2 (10)_{10}=(1010)_{2} (10)10=(1010)2, ( 1010 ) 2 < < 1 = ( 10100 ) 2 = ( 20 ) 10 (1010)_{2}<<1=(10100)_{2}=(20)_{10} (1010)2<<1=(10100)2=(20)10
反过来,可以得到上述结论。
动态规划
由二进制的两条性质得到递推公式:
d
p
[
i
]
=
{
d
p
[
i
−
1
]
+
1
i
为
奇
数
d
p
[
i
/
/
2
]
i
为
偶
数
dp[i]=\left\{\begin{array}{ll}{dp[i-1]+1} & {i为奇数} \\ {dp[i//2]} & {i为偶数}\end{array}\right.
dp[i]={dp[i−1]+1dp[i//2]i为奇数i为偶数
复杂度分析
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
Python
class Solution:
def countBits(self, num: int) -> List[int]:
dp=[0]*(num+1)
for i in range(1,num+1):
if(i%2==1):
dp[i]=dp[i-1]+1
else:
dp[i]=dp[i//2]
return dp