


可以使用动态规划(DP)或位运算来高效求解这个问题。以下是几种常见的解法:
方法 1:动态规划 + 最高有效位
def countBits(n):
ans = [0] * (n + 1)
highBit = 0 # 记录当前的最高有效位
for i in range(1, n + 1):
if (i & (i - 1)) == 0: # 当 i 是 2 的整数次幂时,更新最高有效位
highBit = i
ans[i] = ans[i - highBit] + 1
return ans
# 示例
print(countBits(5)) # 输出: [0, 1, 1, 2, 1, 2]
思路:
- 最高有效位是指二进制表示中最高的
1位置,例如1(2),10(2),100(2),1000(2), … - 如果
i是2^m,它的二进制只有 1 个1,此时更新highBit - 其他数
i的 1 的个数等于i - highBit的 1 个数加 1
方法 2:动态规划 + 最低设置位
def countBits(n):
ans = [0] * (n + 1)
for i in range(1, n + 1):
ans[i] = ans[i & (i - 1)] + 1 # 去掉最低位的1
return ans
# 示例
print(countBits(5)) # 输出: [0, 1, 1, 2, 1, 2]
思路:
i & (i - 1)会去掉i的最低位1ans[i]直接继承ans[i & (i - 1)],再加 1
方法 3:直接计数
def countBits(n):
return [bin(i).count('1') for i in range(n + 1)]
# 示例
print(countBits(5)) # 输出: [0, 1, 1, 2, 1, 2]
思路:
- 直接转换成二进制字符串并统计
1的数量 - 适用于
n较小的情况,时间复杂度O(n log n)
方法 4:位运算 + 记忆化
def countBits(n):
ans = [0] * (n + 1)
for i in range(n + 1):
ans[i] = ans[i >> 1] + (i & 1)
return ans
# 示例
print(countBits(5)) # 输出: [0, 1, 1, 2, 1, 2]
思路:
i >> 1表示i右移一位,相当于i // 2i & 1取得i的最低位ans[i] = ans[i >> 1] + (i & 1)
这几种方法都能高效解决问题,推荐使用 动态规划 + 最低设置位 或 动态规划 + 最高有效位,时间复杂度都是 O(n)。
1139

被折叠的 条评论
为什么被折叠?



