leetcode 位运算(一)

191. 位1的个数

https://leetcode-cn.com/problems/number-of-1-bits/

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

示例 1:输入:00000000000000000000000000001011,输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
示例 2:输入:00000000000000000000000010000000,输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
示例 3:输入:11111111111111111111111111111101,输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

思路:
一:python,借助python的库函数,bin(将数值转换成对应的二进制),再转换成字符串,找出字符串中1的个数。

class Solution(object):
    def hammingWeight(self, n):
        """
        :type n: int
        :rtype: int
        """
        res = 0
        rec = str(bin(n))
        for c in rec:
            if c == "1":
                res += 1
        return res

二:利用n&(n-1),参考http://blog.sina.com.cn/s/blog_8d15072b0102wdfu.html

class Solution(object):
    def hammingWeight(self, n):
        res = 0
        while n > 0:
            n &= (n - 1)
            res += 1
        return res

n&(n-1)的妙用

 下面转自http://blog.sina.com.cn/s/blog_8d15072b0102wdfu.html

leetcode第191题求一个整数的二进制中1的个数。比如8为1000,则有1个1,7为0111,则有3个1.

这题用常规思路很容易解决。但是报出超时的错误,百度得到n&(n-1)的妙用:

原理:n与n-1的区别在于,对于n,从右向左数的第一个"1"开始一直到右,和n-1,完全相反。

例如 8 =1000 7 = 0111,可以看出,8的从右向左数第一个1开始,他的左边和7完全相反。

为什么能够通过n&(n-1)来计算1的个数呢,原理:n&(n-1)是把左边数第一个1变为了0,每次都是进行这么个运算,也就是说没有必要考虑不是1位,这就实现了跳跃式检测。 每次用n&=(n-1),都会自动跳过n%1=0的部分(常规求二进制会这么做)。

弄明白了n&(n-1)的作用,那它有哪些应用?
1. 求某一个数的二进制表示中1的个数

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

2. 判断一个数是否是2的方幂

n > 0 && ((n & (n - 1)) == 0 )

3. 计算N!的质因数2的个数。
容易得出N!质因数2的个数 = [N / 2] + [N / 4] + [N / 8] + ....
下面通过一个简单的例子来推导一下过程:N = 10101(二进制表示)
现在我们跟踪最高位的1,不考虑其他位假定为0,
则在
[N / 2]    01000
[N / 4]    00100
[N / 8]    00010
[N / 8]    00001
则所有相加等于01111 = 10000 - 1
由此推及其他位可得:(10101)!的质因数2的个数为10000 - 1 + 00100 - 1 + 00001 - 1 = 10101 - 3(二进制表示中1的个数)

推及一般N!的质因数2的个数为N - (N二进制表示中1的个数)

目前看到只有这些应用,但只要理解了n&(n-1)的原理及作用,在碰到相关问题时也会比较容易解决。

发布了46 篇原创文章 · 获赞 1 · 访问量 5040

猜你喜欢

转载自blog.csdn.net/qq_xuanshuang/article/details/105022897
今日推荐