【AcWing 26】. 二进制中1的个数 / 输入一个 32 位整数,输出该数二进制表示中 1 的个数

题目描述
输入一个 32 位整数,输出该数二进制表示中 的个数。

注意
负数在计算机中用其绝对值的补码来表示。

数据范围
−100 ≤ 输入整数 ≤ 100

样例1

输入:9
输出:2
解释:9的二进制表示是1001,一共有2个1。

样例2

输入:-2
输出:31
解释:-2在计算机里会被表示成11111111111111111111111111111110,一共有31个1。

AC code 1 & 思路1

代码可直接复制

class Solution {
public:
    int NumberOf1(int n) {
        int res = 0;
        for (int i = 0; i < 32; i ++)
            res += n >> i & 1;//如果n的第i位是1,则res+1;否则什么也不会发生
        return res;
    }
};

思路:循环(固定次数)

一个 int 类型的变量有 32 位,想要取出第 i 位就是 n >> i & 1,因为1的二进制是000…01所以和任何数进行&运算结果都只可能是0或1。

AC code 2 & 思路2

class Solution {
public:
    int NumberOf1(int n) {
        unsigned int x = n;
        int res = 0;
        while (x) res += x & 1, x >>= 1;
        return res;
    }
};

思路:循环(不固定次数)

在第一种方法的基础上,我们可以用while来做这道题,先看一眼代码(上)

这边有一个问题是,如果是负数的话,每次右移运算都会在左边补1,这会造成循环永远不终止,所以这边可以给它转成无符号整型,这就不会出现问题了。

AC code 3 & 思路3

class Solution {
public:
    //返回x的lowbit值
    int lowbit(int x)
    {
        return x & (-x);
    }
    int NumberOf1(int n) {
        int res = 0;
        while (n)
        {
            n -= lowbit(n);//每次减去lowbit(n)
            res ++;
        }
        return res;
    }
};

思路:lowbit

先说一下lowbit是什么东西。

lowbit(x)表示x的最后一位1,比如10的二进制表示是1010,那lowbit(x)就应该是(10)2也就是2。

那lowbit(x)怎么求呢?

其实很简单,只要返回x&(-x)就行了。可又为什么呢?

是因为C++中的负数使用补码表示的,而补码等于反码(就是把x的二进制中的每一位都取反)+1,所以x&(-x)=x&(~x+1)。

要证明x&(~x+1)的正确性,可以先看下图:

很明显,红色数字左边的原码与补码都是相反的,而红色数字右边的原码与补码都是0,所以最后只有红色数字一个1,故x&(-x)是成立的。

那么这道题可以让n反复减去lowbit(n),直到n为0,减去的次数就是答案。

好了,这就是这篇题解的全部内容。如果觉得好的话,不妨给我一个赞吧!如果觉得有问题,也请在评论区指出。

那么,感谢观看!Thanks♪(・ω・)ノ!

改编自AC Wing上的 天元之弈 的题解:AcWing 26. 二进制中1的个数(三种方法、超详细!!!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值