给定一个整数x(x >= 1 && x <= 2000000000),求1到x中所有整数二进制表示中1的总数。
比如x= 5
1的二进制表示为1
2的二进制表示为10
3的二进制表示为11
4的二进制表示为100
5的二进制表示为101
所以1的总数为7
对于这么大的数据,将所有结果打表保存,内存吃不消,打表的时间也要很久。
我们换个思路,做一张特殊的表sum[33], sum[x]代表:1到2^x - 1内所有1的总数。
求sum的时候我们可以得到一个递推关系:
1)当最高位为0的时候,得到sum1 = sum[x - 1]
2)当最高位为1的时候,得到sum2 = sum[x - 1] + 2 ^ (x - 1)
sum[x] = sum1 + sum2 = sum[x - 1] + sum[x - 1] + 2 ^ (x - 1)
我们用函数f(x)代表1到x中所有整数二进制表示中1的总数。
我们会得到另一个递推关系:
bitSum为x的二进制位数,比如5(101) =》bitSum = 3
1)当最高位为0的时候,得到sum1 = sum[bitSum - 1]
2)当最高位为1的时候,得到sum2 = 1到((1 << (sumOfBit - 1)) ^ x)中所有整数二进制表示中1的总数 + 最高位统计次数
sum2 = f((1 << (sumOfBit - 1)) ^ x) + ((1 << (sumOfBit - 1)) ^ n) + 1
f(x) = sum1 + sum2 = sum[bitSum - 1] + f((1 << (sumOfBit - 1)) ^ x) + ((1 << (sumOfBit - 1)) ^ n) + 1
效率为log2(x)