剑指offer-二进制中1的个数

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

常规思路:每次将整数右移一位,而后使用位与运算&1,可是该方法只适用于正数。spa

public class Solution {
    public int NumberOf1(int n) {
        int ans = 0; //记录1的个数
        while(n != 0){
            if((n & 1) == 1)
                ans++;
            n = n >> 1;
        }
        return ans;
    }
}

若是传入的参数为负数则会陷入死循环,好比0x80000000,当把负数右移一位时,高位会补1,最终变为0xFFFFFFFF,程序为陷入死循环。code

 

解决方案:blog

若是传入参数为负数,咱们能够不移动传入参数,而是移动值为1的flag变量,该方法每次须要移动32位。时间复杂度O(N)。io

public class Solution {
    public int NumberOf1(int n) {
        int ans = 0;
        int flag = 1;
        while(flag != 0){
            if((n & flag) != 0)
                ans++;
            flag = flag << 1; //每次向左移动flag的值,从右往左与n的每一位作位与运算
        }
        return ans;
    }
}

 

最优解:n二进制中有几个1,就遍历几回的。class

public class Solution {
    public int NumberOf1(int n) {
        int ans = 0; //记录1的个数
        while(n != 0){
            n = n & (n - 1); //好比1000,1000 & (1000 - 1) = 0,全部就只有一个1
            ans++;
        }
        return ans;
    }
}
相关文章
相关标签/搜索