方法一:按二进制位遍历
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来计数。