跳至主要內容

15-二进制中1的个数

daipeng大约 1 分钟

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

第一种 无符号右移

用1去和n做与运算,然后检查最低位是否是1,然后将n做无符号右移操作。有符号的右移是>>,无符号的右移是>>>。这两者的区别主要在于对负数的移位操作,前者对负数右移会在最高位补1,后者不会。所以右移操作需要使用无符号的右移,如果使用有符号的右移,当为负数时,会出现无限循环的问题。

 public int NumberOf1(int n) {
        int count = 0;
        while (n != 0) {
            if( (n & 1) == 1){ //如果最后一位是1,那么就计数
                count++;
            }
            n = n >>> 1;
        }
        return count;
    }

第二种 左移

我们可以将第一种方法反过来,n不动,让1不断的向左移位,与n做与运算。java中int是32位,所以循环次数为32次。

 public int NumberOf1(int n) {
        int flag = 1;
        int count = 0;
        while (flag != 0) {
            if( (n & flag) != 0 ){
                count++;
            }
            flag = flag << 1;
        }
        return count;
    }

第三种 与运算技巧

先来看一个运算。 10 = 1010 10 - 1= 9=1001 1010 & 1001 = 1000 可以得到一个结论,数字n与数字n-1做与运算,会将n最右边的1变为0。即n中有多少个1,就可以进行多少次这样的计算。

 public int NumberOf1(int n) {
        int count = 0;
        while (n != 0) {
            count++;
            n = (n - 1) & n;
        }
        return count;
    }