一道华为的面试算法题

题目

计算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;
}
posted @ 2022-09-16 23:08  Rogn  阅读(286)  评论(0编辑  收藏  举报