一道华为的面试算法题
题目
计算1~n中每个数的二进制表示中1的个数之和,例如f(5)=7, f(6)=9
思路:
把n表示成二进制形式,从前往后考虑所有1出现的位置,
对于第i为为1,
如果选0,后面n位可以任选,1的个数:\(1*C(n,1) + 2*C(n,2) + ... + n*C(n,n) = n*2^{n-1}\)
如果选1,1的个数等于后缀的大小+1, 0~后面的值
当然,现实的时候,可以从低位往高位累加
应该用数位DP也能做吧
不到10行代码
int cal(int x) {
int res = 0;
for(int i = 0;i < 32;i++) {
if(x & (1<<i)) {
res += i*(1<<(i-1)) + (x&((1<<i)-1)) + 1;
}
}
return res;
}
个性签名:时间会解决一切