面试题15: 二进制中1的个数

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

难度简单

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

示例 1:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例 2:

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 **00000000000000000000000010000000** 中,共有一位为 '1'。

示例 3:

输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 **11111111111111111111111111111101** 中,共有 31 位为 '1'。

int4 个字节,一个字节占 8 位,int36 位。 在计算机内存中以二进制来表示数字,例如int n = 9n 在内存中表示为 00000000000000000000000000001001
解答:
第一种思路
逐位计算,将 n 与 1 进行与运算,如果结果为 1, 则 result ++。每次与运算后,将 n 向右移1位。循环移动,直到 n == 0;
例如 int n = 9, 二进制位表示为 1001。
1001 & 0001 = 1, 1001 >>> 1 = 100。

public class Solution {
   // you need to treat n as an unsigned value
   public int hammingWeight(int n) {
       int result = 0;
      
       while( n != 0){
         if((n & 1) == 1)
           result ++;
         n >>>= 1;  // >>> : Java 中表示无符号的移位,使用 >> 会超时。 
       }
       
       return result;
   } 
}

时间复杂度为 O(n),n 是 二进制的长度。
空间复杂度为 O(1)。

第二种
利用 n & (n-1)。
n-1: 将n中最右边的1 变为 0,最右边 1 的右边所有 0 变 1,例如 11000 (24), 减一后, 10111 (23)。
n & ( n-1 ) : 将n中最右边的 1 变为 0, 例如 11000 & 10111 = 10000。
循环利用 n & (n-1),每次能将 n 中最右边的 1 去掉。直到 n == 0 退出循环, n 中有多少个1,循环就进行多少轮。所以可以统计循环的次数,即能得到 n 中有多少个1。

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        int result = 0;
        while( n != 0){
            result ++;
            n = n & (n-1);
        }
        return result;
    } 
}

时间复杂度:O(m) : m 为二进制数中 1 的个数。
空间复杂度为 O(1)

利用第二种方法,大大提升了运行的时间。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容