整数的二进制表达式中有多少个1

题目:

给定一个32位整数n,可为0,可为正,也可为负,返回该整数二进制表达中1的个数

解法:

一、最简单的解法

整数n每次进行无符号右移一位,检查最右边的bit是否为1来进行统计,代码如下:

public int count1(int n){
    int res=0;
    while(n!=0){
        res+=n&1;
        n>>>=1;
    }
    return res;
}

上面这个方法在最复杂的情况下要经过32次循环

二、下面看一个循环次数只与1的个数有关的解法。

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

三、与count2方法复杂度一样的是如下代码中的count3方法:

public int count3(int n){
    int res=0;
    while(n!=0){
        n-=n&(~n+1);
        res++;
    }
    return res;
}

每次进行n-=n&(~n+1)操作的时候,是移除最右侧的1的过程,等号右边n&(~n+1)的含义是得到n中最右侧的1,这个操作在位运算的题目中常出现。例如:n=01000100,n&(~n+1)=00000100,n-n&(~n+1)=01000000。

四、一种看起来很“超自然”的解法,平行算法

public int count4(int n){
    n=(n&0x55555555)+((n>>>1)&0x55555555);
    n=(n&0x33333333)+((n>>>2)&0x33333333);
    n=(n&0x0f0f0f0f)+((n>>>4)&0x0f0f0f0f);
    n=(n&0x00ff00ff)+((n>>>8)&0x00ff00ff);
    n=(n&0x0000ffff)+((n>>>16)&0x0000ffff);
}

参考自:《程序员代码面试指南》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值