第一天:比特位记数
给你一个整数 n
,对于 0 <= i <= n
中的每个 i
,计算其二进制表示中 1
的个数 ,返回一个长度为 n + 1
的数组 ans
作为答案。
示例 1:
输入:n = 2 输出:[0,1,1] 解释: 0 --> 0 1 --> 1 2 --> 10
这个题就是找二进制中的1,刚开始看到计算二进制的值第一反应还没有思绪,用草稿纸将数字写到11就发现了规律,这个二进制中的1和当前计算的数是奇数,还是偶数有关,当数字
当数字为奇数时,设数字为A,A中的二进制中的1的个数结果就是A除以2向下取整(这里设为B)的二进制数1的个数加1。
当数字为偶数时,设当前数字为A,A中的二进制中的1的个数结果就是A除以2(这里设为B)的二进制数1的个数。
例如:
当A为17时: 17除以2向下取整为8(设为B),B的二进制位数中1有1个,A是奇数,所以得到1+1=2,这就是17的二进制中1的个数。
当A为22时: 22除以2向下取整为11(设B),B的二进制位数中1有3个,A是偶数,所以得到3,这就是22的二进制中1的个数。
很明显,这个里面存在着子问题,使用动态规划解决能够提升很多的时间。
上代码:
class Solution:
def countBits(self, n: int) -> List[int]:
res=[0 for i in range(n+1)]
for i in range(1,n+1):
if i%2==0: # 当i为偶数时
res[i]=res[i//2]
else: # 当i为奇数时
res[i]=res[i//2]+1
return res
另外在计算数字中的二进制数时,看到一位博主方法的另外一种方法不错,
使用的是逻辑与运算得到,在不计算子问题的时候也提升了很多的速度。
0011 0100 - 1 = 0011 0011
0011 0100 & 0011 0011 = 0011 0000 // 计数一个1
0011 0000 - 1 = 0010 1111
0011 0000 & 0010 1111 = 0010 0000 // 计数两个1
0010 0000 - 1 = 0001 1111
0010 0000 & 0001 1111 = 0000 0000 // 计数三个1,程序停止
具体详情查看