题目描述
LC338 比特位计数
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]
解题思路
二进制数如x=100110,其与x-1做&运算,会把x的最后一个1置为0。
原因:
1.假设x的最低位的1在最后一位,则x-1的最后一位是0,其余位数相同,做&运算,显然会把x的最低位1置0;
2.假设x的最低位的1不在最后一位,显然最低位1之后的位都是0,则减去1后明显原最低位的1的值变为0,后面的0全部变为1,做&运算显然原最低位1变成0,其余位数保持不变。
也就是说x的二进制表示里1的个数,等于x&(x-1)的二进制表示的1的个数+1。
即result[x] = result[x&(x-1)] + 1,而result[0] = 0,由此可按规律推导出1、2、3…、n的二进制表示里1的个数。
代码
func countBits(num int) []int {
result := make([]int, num+1)
result[0] = 0
for i := 1; i<= num; i++ {
result[i] = result[i&(i-1)]+1
}
return result
}