剑指offer_二进制中1的个数

题目要求

时间限制:1秒 空间限制:32768K

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

分析实现

这道题看起来比较简单,直观来看将n直接右移即可,如下:

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         while(n)
         {
             //这样做可能引起死循环
             if(n&1)count++;
             n=n>>1;
         }
         return count;
     }
};

然而发现测试过不了,仔细想一下,输入一个负数时,比如0x80000000,右移时符号位也会保留,最后会变成0xFFFFFFFF造成死循环。为避免这种死循环,可以使用左移。
代码如下:

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         unsigned int flag=1;
         while(flag)
         {
             if(n&flag)count++;
             flag=flag<<1;
         }
         return count;
     }
};

实际上还有一种更巧妙的做法。一个整数减去1后再和原来的整数做位与运算,得到的结果相当于把整数的二进制的最右边的1变成0。根据这种思路,可以得到代码:

class Solution {
public:
     int  NumberOf1(int n) {
         int count = 0;
         while(n)
         {
             count++;
             n=(n-1)&n;
         }
         return count;
     }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值