Write a function that takes an unsigned integer and return the number of '1' bits it has (also known as the Hamming weight).
Example 1:
Input: 00000000000000000000000000001011
Output: 3
Explanation: The input binary string 00000000000000000000000000001011 has a total of three '1' bits.
Example 2:
Input: 00000000000000000000000010000000
Output: 1
Explanation: The input binary string 00000000000000000000000010000000 has a total of one '1' bit.
Example 3:
Input: 11111111111111111111111111111101
Output: 31
Explanation: The input binary string 11111111111111111111111111111101 has a total of thirty one '1' bits.
//这次没有指定是32位的,想到int在首位1之前的0都是没有意义的,所以感觉可以按10进制求余数去计数,第一次尝试
//但是一串1肯定超出了int的范围,所以第二次试一下采用原数值依次右移一位与1相与的方法
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res=0;
while(n!=0){
if((n&1)==1){
res++;
}
n>>=1;
}
return res;
}
}
提交之后结果报错超时了。
【分析】正数是可以这样判断的,但是负数不可以:因为最高位的1会在移动的过程中变化为数值,负数也会随着变成正数。比如0x8000-0000,当右移一位变成0x0400-0000,这样是不对的,因为移位前是一个负数,所以我们要保证移位后的数也是一个负数,因此移位后改数变为0xC000-0000.(也就是说在移位的过程中1000不应该变成0100而应该变成1100),如果保持最高位是1的话,最高位永远都是1,最终这个数字会变成0xFFFF-FFFF,程序陷入死循环。(也就是变成了1000》1100》1110》1111)
于是在网上查到了以下代码,思路一样的,但是没问题的。于是发现是位移的写法有差别。
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
while (n != 0) {
count += n&1;
n >>>= 1;
}
return count;
}
}
把 n >>= 1;改成 n >>>= 1;之后,自己写的代码也通过了,但不太明白为啥有差别。
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res=0;
while(n!=0){
if((n&1)==1){ //注意这句必须有括号
res++;
}
n>>>=1;
}
return res;
}
}