【剑指offer】11 二进制中1的个数

题目地址:二进制中1的个数

 

题目描述                                   

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

题目示例                                   

输入:
10
返回值:
2

 

解法分析                                   

解这道题需要了解源码、反码和补码的相关知识。

首先我们可以从右移操作入手,一个整数若右移1,如果最右位是0,那么相当于该整数除以2,如果最右位是1,那么相当于先减1再除以2(其实就是看除以2之后是奇数还是偶数),因此我们可以由此得到算法1;

但我们会发现,这样会需要我们循环32次(因为该数表示为32位二进制),有没有更快的算法呢?

当我们用一个整数,去和比其小1的整数做与运算时,该整数最右位的1会变成0。比如6(1010)和5(1001)做与运算,结果是1000,可以发现1010最右侧的1变成了0。我们可以使用这个方法来计算n包含几个1,且运算次数与n中1的个数相同。此方法对以补码表示的负数同样适用。见算法2。

 

代码                                         

算法1:

 1 function NumberOf1(n)
 2 {
 3     // write code here
 4     var num = 0;
 5     var m,k;
 6     for(var i=0;i<32;i++){
 7         m = n/2;
 8         k = n >> 1;
 9         if(m != k){
10             num++;
11         }
12         n = Math.floor(m);
13     }
14     return num;
15 }

算法2:

 1 unction NumberOf1(n)
 2 {
 3     // write code here
 4     var num = 0;
 5     while (n){
 6         n = n & (n-1);
 7         num++;
 8     }
 9     return num;
10 }

 

执行结果                                   

 

posted @ 2021-01-07 15:38  月南君  阅读(78)  评论(0编辑  收藏  举报