题目:https://www.nowcoder.com/ta/coding-interviews
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
求整数的补码:
1、正整数的补码是其二进制表示,与原码相同;
例如:5(00000101)
2、负整数的补码:将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1。
例如:-5对应正数5(00000101)→所有位取反(11111010)→加1(11111011)
根据补码求原码:
已知一个数的补码,则对应原码为:对该补码再求补码。
python中得到一个数n的补码:n & 0xffffffff(这个做法来自网络,具体原因未知),
所以直接的做法如下:
1 | class Solution1: |
1 | method = Solution1() |
32
把一个整数减去1之后再和原来的整数做按位与,得到的结果相当于是把整数的二进制表示中最右边的一个1变成0,一个整数的二进制表示有多少个1则可以进行多少次这样的操作
根据上述特点可以得到一种求解方案,这也是《剑指offer》一书提供的精巧思路
1 | class Solution2: |
1 | method = Solution2() |
32
以下也是一种特别的方案,来自参考链接中的博主。
具体是:将负数-n转换为正n,然后计算(n-1)中的1的位数,再用32减之,刚好得到负数补码中1的位数
1 | class Solution3: |
1 | method = Solution3() |
32
1 | bin(-11) |
'-0b1011'
1 | bin(-11).replace('0b','') |
'-1011'
移位操作:(确定位长)
1 | class Solution4: |
1 | method = Solution4() |
32
另一种移位操作:(确定位长)
1 | class Solution5: |
1 | method = Solution5() |
32
参考:
1、https://blog.csdn.net/Datawhale/article/details/82182612
2、https://blog.csdn.net/fuxuemingzhu/article/details/79512764
1 |