昨天的题不是不是很难,都会有自己的解法.
class Solution(object):
def countBits0(self, num: int):
"""暴力统计"""
res = []
for i in range(num + 1):
res.append(bin(i).count("1"))
return res
def countBits1(self, num):
"""
因为我发现当i是偶数时,和前一个计算有关联,那就是右移到当前数不是偶数时的次数就是上一次需要少掉的1的次数,同时加上这次的1
:type num: int
:rtype: List[int]
"""
if not num:
return [0]
pre_list = [0 for _ in range(num + 1)]
pre_list[1] = 1
for i in range(2, num + 1):
count = 0
if not i & 1:
c = i
while not (c & 1):
# 统计需要减掉1的个数
count -= 1
# 右移
c >>= 1
# 更新i位置的值
pre_list[i] = pre_list[i-1] + count + 1
return pre_list
def countBits2(self, num: int):
def countOnes(x: int) -> int:
ones = 0
while x > 0:
# x &= (x - 1) 当x=0的时候,&的次数就是x中1的个数
x &= (x - 1)
ones += 1
return ones
bits = [countOnes(i) for i in range(num + 1)]
return bits
def countBits3(self, num: int):
"""
dp过程,计算i中的1的个数,可以改为bits[i - highBit] + 1,其中highBit就是比i小的,
2的次数放也就是 2 ** x = highBit < i, 这个时候bits[i - highBit] + 1就是他的值
"""
bits = [0]
highBit = 0
for i in range(1, num + 1):
# 判断是否是偶数,其实可以用i & 1
if i & (i - 1) == 0:
highBit = i
bits.append(bits[i - highBit] + 1)
return bits
def countBits4(self, num: int):
"""
如果i为偶数的时候,统计1的个数,这个时候i的二进制最后一位必定是0,这个时候和i>>1的1的个数是相等;
如果i是奇数的时候,统计1的个数,这个时候可以给i-1它就变成了偶数,这个时候(i-1) >> 1 + 1和i中1的个数相等,为什么+1,减一之后的补偿
"""
bits = [0]
for i in range(1, num + 1):
bits.append(bits[i >> 1] + (i & 1))
return bits
def countBits(self, num: int):
"""
这个很有意思,它的意思是找比i最小的偶数,然后再它的bits结果上+1
因为是二进制,所以你将前16位二进制表示写出来之后,你会发现一个偶数的二进制,总比后面(也就是比他大的数)两个数少一个1
"""
bits = [0]
for i in range(1, num + 1):
bits.append(bits[i & (i - 1)] + 1)
return bits
if __name__ == '__main__':
s = 10
s1 = Solution()
root = s1.countBits(s)
print(root)