leetCode 191. Number of 1 Bits

    题目链接:https://leetcode.com/problems/number-of-1-bits/

    题目内容:

Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).

For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3.

    题目分析:

    这道题我选择当一回《编程之美》的搬运工,在“求二进制数中1的个数”这一节有详细的说明。

    1> 首先是我自己的一种解法,定义一个uint_t的变量作为测试位,初始化为1,即00000000000000000000000000000001,用移位的方式测试给定数的每一位,并加到计数器中。其中要取得给定数n在某一位上的数字,还需要将测试位和n的“与操作”的结果做一个移位,所以的数目为迭代的次数。具体如代码所示

class Solution {
public:
    int hammingWeight(uint32_t n) {
    	int count = 0;
    	uint32_t test = 1;
    	for(int i=0;i<32;i++) {
    	    count += (n&test) >> i;
    	    test <<= 1;
    	}
    	return count;
    }
};

    2> 上述运行的结果是8ms,但是其实没什么必要定义一个测试位,只要每次让给定数n右移,并与0x01做“与操作”就能得到每一位上的数字,这就是《编程之美》上面的解法二,测试了下,的确要快了一些,用了4ms,至少在这道题上是这样。

int count = 0;
for (int i = 0; i < 32; i++) {
    count += n&0x01;
    n >>= 1;
   }
return count;
    3> 下面祭出编美里的第一种解法,其实也是最容易想到的,编美上第一种解法往往不是最好的,从分析来看的确是这样,通过除法和取余的操作肯定比位运行慢,因为bit才是计算机最喜欢的语言。原理是这样的,每次对n取余,这样的结果肯定就是最后一位的数字,用计数器加起来,这样之后将n除以2,表示往右移了一位。比较打脸的是,该解法的在这道题的运行速度上也是4ms。

int count = 0;
    while(n) {
        if(n % 2 == 1)
    	    count++;
    	n /= 2;
    }
    	return count;

    4> 按照编美上面的解释,也的确有道理,有些零的位没必要做测试或者累加操作,只计算当前的某一个1就行了,直接贴出解法。

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


    又一次打脸的是,这个解法也是用了8ms。。。当然,编美上面还有传统的暴力打表法,向来是oj中最为不耻但是效率最好的,毕竟下标O(1)啊。

    补充一下:在这道题中已经指明了是unsigned int,因此是不用考虑负数的。假设输入的参数中规定是整数,即n可能为负数,这时候解法2就失效了,因为对于带符号的整数右移,如果整数n是正数,右移的时候会在最左也就是最高位补0,这没问题;如果n是负数,为了保证右移后还是负数,右移的时候会在最左也就是最高位补1,这样最后整个数变成0XFFFF而导致死循环,因此要根据输入的类型选择算法,按照编美和剑指offer的推荐首选解法4.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值