题目:

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路:

1.c和java底层是补码二进制,直接用位运算计数,就是负数的补码右移是补1,左移补0,所以右移无穷1,所以得限制int 32个位。
2.题解区里的巧妙思路,既然底层是二进制了,可不可以直接统计出1的个数而不是遍历,当为正数时,-1操作肯定是让第一个1(不管你有多少个1)变为0,则n&(n-1)就是刚好让第一个1在内后面全部0掉,于是可以利用这个删除1的思路来统计,又类似于快速幂,对于负数,负数补码-1是添0,所以也是删除1的操作,而且删到最后负数越界那里又回到0,所以是统一操作。

#include <iostream>
using namespace std;
class Solution {
public:
    int  NumberOf1(int n) {
        int sum = 0, count=32;
        while(n && count--){
            if(n&1){
                ++sum;
            }
            n=n>>1;
        }
        return sum;
    }
    int  NumberOf2(int n) {
        int sum= 0;
        while(n){
            n = n&(n-1);
            ++sum;
        }
        return sum;
    }
};