十六、二进制中1的个数

描述:

输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
示例1
输入:10
返回值:2

考点:

这是一篇面对初级coder的题解。
知识点:二进制,位运算
难度:一星

方法一:暴力方法

分析:题目给一个有符号的整数int,求整数转化成二进制数后,1的个数。
直接根据题目的描述来提出方法一。有2个问题:
问题1: 如何从十进制数转化到二进制数?
问题2:转化为二进制数后,如果判断有1的个数?
方法1:除2取模法。

class Solution {
public:
     int  NumberOf1(int n) {
         int ans=0;
         while(n!=0)
         {
             int tmp=n%2;
             if(tmp==1)
                 ans++;
             n/=2;
         }
         return ans;
     }
};

当然这种方法,对于大部分数据是对的,但是对于-2147483648,二进制为1000…000,一共有31个0.因为计算机使用补码存储二进制数据的。对于这个数据,我们的方***输出0,实际上为1.所以这种方法不对。
方法2:二进制移位法
直接将整数看成二进制,然后采用移位的方法

class Solution {
public:
     int  NumberOf1(int n) {
         int ans=0;
         while(n!=0)
         {
             if(n&1)
                 ans++;
             n>>=1;
         }
         return ans;
     }
};

代码中val & 1表示val 与 0x000…0001(其中有31个0)进行 & 操作。
val >>= 1表示,如果val的二进制是110,则操作之后会变成011,也就是舍去最低位,然后最高位补0.
但是如果val为负数,最高位会补1,所以对于负数还是有点问题。
我们可以转换一下思路,让一个数0x01从右向左与val的每一位进行&操作来判断

class Solution {
public:
     int  NumberOf1(int n) {
         int ans=0;
         int mark=0x01;
         while(mark!=0)
         {
             if(mark&n)
                 ans++;
             mark<<=1;
         }
         return ans;
     }
};

这个算法可以解决此题,但是需要运行32次。
时间复杂度:O(32)
空间复杂度:O(1)

方法 二:技巧法

对于上一种解法中,无用操作是,如果当前位是0, 还是会做判断,然后一位一位的移动。
如果,给你一种超能力,你一下可以对从右向左的第一位1直接判断,遇到0直接略过,那效率是不是很快。

现考虑二进制数:val :1101000, val-1: 1100111 那么val & (val-1) : 1100000
如果你会了这个操作,是不是这题就很简单了。

class Solution {
public:
     int  NumberOf1(int n) {
         int ans=0;
         while(n!=0)
         {
             ++ans;
             n=n&(n-1);
         }
         return ans;
     }
};

时间复杂度:O(n) n为val中1的个数
空间复杂度:O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值