题目:
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
例子:
例如,把9表示成二进制是1001,有2位是1。因此如果输入9,则该函数输出2。
问题解析:
- 基本的二进制位运算题
链接:
剑指Offer(第2版):P100
思路标签:
算法:位运算
解答:
1. C++
常规解法:
- 因为是统计1的个数,那么用输入整数的每一位与1的位与运算就可以简单的实现,重点是如何遍历整数的每一位;
- 如果对整数进行移位操作,那么整数需要进行右移运算,这个时候如果输入整数为负数,那么移位操作后整数的左边的n位则均变为1,最终变成0xFFFFFFFF导致死循环;
- 所以这里对整数1进行移位操作,那么对1进行左移运算。
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
int flag = 1;
while(flag){
if(n & flag)
count++;
flag = flag << 1;
}
return count;
}
};
无须移位操作的解法:
- 我们将一个整数如1100,减去1后,变成1011。整数最右边的1变成0,1后面的0都变成1,1前面的数均不变。
- 所以再将1100和1011做位与运算后,相当于把减1后的数末尾的1变0。
- 整体来说就是将整数最右边的1变成0,一直到整数变为0为止。有多少个1就能有多少的操作。相比于常规解法更加简单。
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while(n){
count++;
n = (n-1) & n;
}
return count;
}
};
相关题目:
问题1:
用一条语句判断一个整数是不是2的整数次方。
- 一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,其他位均为0;
- 把该整数减去1后再和它自己做与运算,那么整数中唯一的1就变成0。
问题2:
输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n。
- 如10的二进制表示为1010,13的二进制表示为1101,所以两个数中不同的位均需要改变,统计两数中不同的位的个数即可;
- 分两步解决:求这两个数的异或;统计结果中1的位数。