一题超多解
Leetcode Link: 338. 比特位计数 - 力扣(LeetCode)
题目
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

解法一
思路: 有规律的
任意一个数字 , 可以写成这种形式: 其中,
这样, 中所含有的数字 1 的个数就是 1 加上数字 所含有的 1 的个数
当数字遍历到 的时候,一定已经走过了,因此这里可以直拿来用
题解:
class Solution:
def countBits(self, n: int) -> List[int]:
if n == 0:
return [0]
res = [0]
for val in range(1, n+1):
m = log2(val)
i = val - 2**floor(m)
n1 = 1 + res[i] if i!=0 else 1
res.append(n1)
return res解法二
思路:暴力法,遍历每个数字,并统计每个数字中 1 的个数
题解:
class Solution:
def countBits(self, n: int) -> List[int]:
res = []
for i in range(n + 1):
res.append(bin(i).count("1"))
return resNote
bin(num): 将十进制数字num转变成二进制表示的数字的字符串形式str.count(c): 统计字符串中str中字符c的个数
解法三
思路:暴力递归 对于数字 , 有如下的情况成立
- 如果 是偶数,那么它的二进制 1 的位数与 的二进制 1 的位数相等
- 因为偶数的二进制末尾是 0,右移一位等于 ,而二进制中 1 的个数没有变化。
- 如果 是奇数,那么它的二进制 1 的位数与 的二进制 1 的位数多 1 个,此时是偶数,回到情况1。即所以奇数 的二进制 1 的个数等于 中二进制 1 的位数 +1.
题解:
class Solution(object):
def countBits(self, num):
res = []
for i in range(num + 1):
res.append(self.count(i))
return res
def count(self, num):
if num == 0:
return 0
if num % 2 == 1:
return self.count(num - 1) + 1
return self.count(num // 2)解法四
思路:记忆化搜索
对解法三进行改进
题解:
class Solution(object):
def countBits(self, num):
self.memo = [0] * (num + 1)
res = []
for i in range(num + 1):
res.append(self.count(i))
return res
def count(self, num):
if num == 0:
return 0
if self.memo[num] != 0:
return self.memo[num]
if num % 2 == 1:
res = self.count(num - 1) + 1
else:
res = self.count(num // 2)
self.memo[num] = res
return res解法五
思路 改写为动态规划
题解
class Solution:
def countBits(self, num):
res = [0] * (num + 1)
for i in range(1, num + 1):
res[i] = res[i >> 1] + (i & 1)
return res启发和联系
[参考1]((https://leetcode.cn/problems/counting-bits/solution/yi-bu-bu-fen-xi-tui-dao-chu-dong-tai-gui-3yog/): 解法三四五