二进制中 1 的个数

二进制中1的个数

http://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8

第三种解法我觉得是最好的,将各个位置上的 1 都相加,就是 1 的个数

题解一

常规解法,循环右移,数个数

public class Solution {
  public int NumberOf1(int n) {

    int count = 0;
    while(n != 0) {
      count += (n & 1);
      n >>>= 1;
    }

    return count;
  }
}

题解二

一个二进制数 n-1 后与原二进制数进行 & 运算( 即 n&(n-1) )会消去最右边的1。

因为 n&(n-1) 每次都消去最右边的 1,最终 1 全被消去会得到 0,所以有几个 1 就可以进行几次 n&(n-1)

public class Solution {
  public int NumberOf1(int n) {

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

    return count;
  }
}

题解三

统计 1 的个数可以转换为将 n 个 1 相加后的结果,即忽略每个位权重的相加。

对于一个二位的二进制数,可能会是 00011011,当它和 01 进行与操作后,得到的值是保留最后一位的结果 记为 n1,当它和 10 进行操作之后,得到的值是保留第一位的结果记为 n2,此时如果将 n2 的值向右移动一位再加上 n1,就是每个位置忽略权重的相加。

一个 int 占 32 个位,先把数分成 16 组(两个数一组),每个组相加后的结果存在原来的位置,这个结果不是忽略权重的相加,其相加结果乘以了两个数中最低位的权重。于是,接下来把数又分为 8 组(四个数一组),将前四个数与后四个数进行最开始的操作,得到的和权重为最低位的。反复进行操作,直到所有和的权重都为 1 时,就是最终的结果

public class Solution {
  public int NumberOf1(int n) {

    int temp = n;

    // 0x55555555 = 0101 0101 0101 0101  0101 0101 0101 0101
    // 0xaaaaaaaa = 1010 1010 1010 1010  1010 1010 1010 1010
    temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >>> 1);

    // 0x33333333 = 0011 0011 0011 0011  0011 0011 0011 0011
    // 0xcccccccc = 1100 1100 1100 1100  1100 1100 1100 1100
    temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >>> 2);

    // 0x0f0f0f0f = 0000 1111 0000 1111  0000 1111 0000 1111
    // 0xf0f0f0f0 = 1111 0000 1111 0000  1111 0000 1111 0000 
    temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >>> 4);

    // 0x00ff00ff = 0000 0000 1111 1111  0000 0000 1111 1111
    // 0xff00ff00 = 1111 1111 0000 0000  1111 1111 0000 0000
    temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >>> 8);

    // 0x0000ffff = 0000 0000 0000 0000  1111 1111 1111 1111
    // 0xffff0000 = 1111 1111 1111 1111  0000 0000 0000 0000
    temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >>> 16);

    return temp;
  }
}
全部评论
请问 什么是消去最右边的一
点赞 回复 分享
发布于 2020-02-07 14:18

相关推荐

感性的干饭人在线蹲牛友:🐮 应该是在嘉定这边叭,禾赛大楼挺好看的
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
6 收藏 评论
分享
牛客网
牛客企业服务