1.问题描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
2.思路
方法1:将二进制变成字符数组,遍历数组统计1的个数,这种办法不需要考虑正负数。
1 public class Solution {
2 public int NumberOf1(int n) {
3 String s = Integer.toBinaryString(n);//将n变成二进制之后变成字符串
4 char[] num = s.toCharArray();//将字符串变成字符数组
5 int count = 0;//定义一个变量,用来计数,统计1的个数。
6 for(int i = 0; i < num.length; i++){//遍历字符数组,统计1的个数
7 if(num[i] == '1'){//判断该位是否是1,如果是1,count就++,否则执行下一次循环。
8 count++;
9 }
10 }
11 return count;//返回1的个数。
12 }
13 }
方法2:一种很巧妙的办法——n&(n-1)
解释一下:n-1之后,就把二进制表示种的从右开始的第一个1变成了0,同时把第一个1右边的0变成了1.例如1100,减1之后就是1011,再和1100(也就是n)进行&运算结果就是1000,然后将结果赋值给n,把最右边的1变成了0,这样循环,直到n变成0停止,循环过程统计1出现的次数即可。
1 public class Solution {
2 public int NumberOf1(int n) {
3 int count = 0;//定义计数器变量
4 while(n != 0){//n不等于0就循环
5 count++;//n不为0,那么n的二进制表示中就必有1,所以count++.
6 n = n&(n-1);//这个过程就是把n的二进制表示的最右边的1变成0,其他位不变,然后再赋值给n。
7 }
8 return count;//返回计数器的的结果。
9 }
10 }
方法3:无符号右移
思路就是把整数n变成二进制表示后逐个判断最低位是否是1,如果是1就让计数器加1,然后进行无符号右移1位,如果不是1,就直接右移1位,直到传入的整数n变成0停止。
(因为无符号位移不管最高位是0还是1,右移之后都用0补齐,所以不需要考虑正负数的问题)
1 public class Solution {
2 public int NumberOf1(int n) {
3 int count = 0;//计数器
4 while(n!=0){//n不为0才执行循环
5 count+=n&1;//这里很巧妙,n&1,用来判断最后以为是不是1,如果是1,执行前面count+=1;如果不是1,那么n&1的结果就是0,count就不变。
6 n = n>>>1;//n的二进制表示想右移一位。
7 }
8 return count;//返回结果。
9 }
10 }