剑指offer第十一题。

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解题思路

这个题目求一个数的二进制形式的1的个数,比较简单的思路是:每次与1进行&操作,看是不是1,是则奇数,无论如何都后移一位再判断。

1
2
3
4
5
6
7
8
9
10
11
12
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n != 0){
if((n & 1)==1){
count++;
}
n = n >>> 1;
}
return count;
}
}

但是,如果输入时负数会陷入死循环,因为负数右移时,在最高位补得是1。那么就死循环了。

比较好的解法是:如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。

循环是判断n是不是为0了,只要不为0,就循环。一进循环说明n是有至少一个1的,二话不说,先count++;

比如:一个二进制数1100,减去1之后是1011。

两者一&则变为1000,原来最右边的1就变成了0.

由于n不为0,则再次进入循环:

1000减去1是0111,两者一&就是0000.退出循环。

我的答案

1
2
3
4
5
6
7
8
9
10
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n != 0){
count++;
n = n & (n-1);
}
return count;
}
}