剑指Offer 面试题15:二进制中1的个数
题目:实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如,9的二进制是1001,有两位是1,那么输入9,函数输出2。
看完题目我就想到了Java中Integer类中的bitCount()方法,记得在leetcode上就是这么偷懒完成accepted的,哈哈!正确的解题思路是让1和该数的二进制表示的每一位相与,若不为零则表示该位是1。遍历二进制表示的每一位并统计结果不为0的次数,就是二进制表示中的1的个数了。容易想到,将输入的数字与1相与,然后将数字一直右移,继续相与。书中说,这样会引起死循环,其实这只是条件判断的区别。比如,输入int类型,那在Java中,就是32位存储的,循环判断32次写死了,就没有问题了;另一种是不右移数字,而是将1一直坐移。下面Java代码就是采用将1左移实现的,其实右移数字也可以。
第一种解法:
public static int numberOfOne(int n){
int count=0;
int flag=1;
for(int i=1;i<=32;i++){
if((n&flag)!=0)
count++;
flag=flag<<1;
}
return count;
}
第二种解法:
该解法基于这样一个事实:把一个整数减1,在和原数相与,会把改整数二进制表示中的最右边的1变成0。
Java代码如下:
public static int numberOfOne2(int n){
int count=0;
while(n!=0){
count++;
n=n&(n-1);
}
return count;
}
采用Integer类的bitCount()来检验算法对不对,测试代码如下:
public static void main(String[] args) {
int[] xArr={0,9,15,-1,-15};
int [] result=new int[xArr.length];
int [] result2=new int[xArr.length];
int [] result3=new int[xArr.length];
for(int i=0;i
方法1结果=[0, 2, 4, 32, 29]
内置API结果=[0, 2, 4, 32, 29]
方法2结果=[0, 2, 4, 32, 29]