题目描述
请实现一个函数,输入一个整数(无符号数),输出该数二进制表示中 1 的个数。
解1
常规的思路可能是将一个数n和1做按位与(&)运算,若结果为1,则证明n的二进制表示中末位为1,计此时符合题目条件,计数器加1,然后将n用n/2赋值,继续上述过程。
但该方法有个问题,针对负数,由于负数在计算机中是以补码的形式存储,所以对于负数不能用这种方法。可以换个思路。保持n不变,设置一个flag,flag从1开始,令n与flag做按位与运算,若为1则计数器加1。然后另flag左移一位,继续上述过程。
public static int countOne2(int x){
int count = 0;
int flag = 1;
while(flag != 0){
if((x & flag) != 0){ //不等于0 因为 9&8 结果为8
count++;
}
flag = flag << 1;
}
return count;
}
2. 巧用 n&(n−1)
public class Solution {
public int hammingWeight(int n) {
int res = 0;
while(n != 0) {
res++;
n &= n - 1;
}
return res;
}
}
相关题目:
● 用一条语句判断一个整数是不是2的整数次方。一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0。根据前面的分析,把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0。
● 输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到 n。比如 10 的二进制表示为 1010,13 的二进制表示为1101,需要改变1010中的3位才能得到1101。我们可以分为两步解决这个问题:第一步求这两个数的异或,第二步统计异或结果中1的位数。