方法一:按二进制位遍历

1.解题思路

题意:
找出给定数的二进制表示中的1的个数。
分析:
暴力解法,将数字按照二进制遍历,并判断当前位是否为1,统计为1的个数即可。

2.解法

n按位与1,如果结果为1,说明n二进制的最后一位是1。接着不断令n右移一位,再判断并统计n二进制末尾1的个数即可。

3.具体代码

class Solution {
public:
    int  NumberOf1(int n) {
        int ans=0;//二进制中1的个数 
        for(int i=0;i<32;i++){//已知32位二进制
            if((n&1)==1)ans++;//二进制最低位是1
            n>>=1;//二进制向右滚动 
        } 
        return ans; 
    }
};

4.时间复杂度和空间复杂度分析

时间复杂度:,据题意32位二进制,按位遍历即可。
空间复杂度:,仅用到了一个整形变量ans来计数。

方法二:位运算

1.解题思路

根据:n&(n-1)将n的二进制中最低位由1变成0
易知:(n-1)<n,(n-1)对应的二进制相比n的二进制,一定是将n的二进制的最后一位1变为0,而将该位后若干0变为1。那现在已知n的二进制最后一位1所在位在(n-1)二进制所对应位为0,而两个数二进制该位前所有位完全一致,所以进行按位与操作n=n&(n-1)即为将n二进制最后一位1置0。

2.解法

不断将n二进制的最后一位1置0,直到n变为0为止。
其实这里也可以取巧下,用库函数。

    return __builtin_popcount(n);

3.图解

图片说明

4.具体代码

class Solution {
public:
    int  NumberOf1(int n) {
        int ans=0;//二进制中1的个数 
        while(n){
            n=n&(n-1);//将二进制下的n的最后一位置0 
            ans++;
        } 
        return ans; 
    }
};

5.时间复杂度和空间复杂度分析

时间复杂度:,n为二进制中的1的个数。
空间复杂度:,仅用到了一个整形变量ans来计数。