面试题10. 二进制中1的个数

来源:互联网 发布:python net snmp 编辑:程序博客网 时间:2024/06/07 18:02

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

思路1:
设置一个标志位1,每次向左移1位,然后与整数进行“与”运算
如果得到的结果不是0,则count加1。

这里写图片描述

“与”运算的次数等于整数的二进制位数,比如32位的整数需循环32次。如果整数的位数是n,则这个方法的时间复杂度是O(n)。

思路1的代码如下:

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

思路2:
n & (n-1) 相当于把n的二进制位中,最右边的一个1变为0

把一个整数,不断与自身减1进行“与”,直到整数变为0。这个过程中,需要多少步,整数就有多少位。
如果整数的二进制数中,1的个数有k个,则这个方法的时间复杂度是O(k),比第一种思路的O(n)要好一点。

这里写图片描述

这样,一个整数中有多少个1,就进行多少次运算。

思路2的代码如下:

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

注意:

有一种思路是,把整数 n 不断向右移动,每一次都判断最后一位是不是1,直到整个整数变为0为止。
当输入的是正整数时,这种方法是可以的。一旦遇到了负整数,这种方法就不适用了。

因为负数的二进制表示中,最高位是符号位1,负数的右移会始终在符号位补1。如果一直做右移,最终这个数字就会变为1111,陷入死循环。

比如-5的二进制表示是11111111 11111111 11111111 11111011,如果一直右移,会不断在最高位补1,那么最终这个数会变为11111111 11111111 11111111 11111111。

附加题:

1、用一条语句判断一个整数是不是2的整数次方。
2的整数次方,比如4(0100)、8(1000),二进制表示中只包含一个1。因此,用n & (n-1)的方式,把二进制中的唯一一个1变为0,整个数就变为0了。也就是说,如果n & (n-1) = 0,那么就是2的整数次方,反之不是。

2、给你两个整数,比如10和13。现在要改变10的二进制,使之等于13。问需要改变多少位。

思路是,先求两个数的异或,然后统计结果中有多少个1。(异或:不同取1)

注:学渣心里苦,不要学楼主,平时不努力,考试二百五,哭 ~

这里写图片描述

原创粉丝点击