Leetcode 201:数字范围按位与(超详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/86064015

给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。

示例 1:

输入: [5,7]
输出: 4

示例 2:

输入: [0,1]
输出: 0

解题思路

首先想到的就是暴力破解,遍历范围中的数,然后对所有数进行and操作。

from functools import reduce
from operator import __and__
class Solution:
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        return reduce(__and__, range(m, n+1))

超时了,果然没这么容易。

我们知道当一个奇数和一个偶数进行and的话,那么最后一位一定是0。如果我们输入的m!=n,那么必然[m,n]这个区间内至少包含一个奇数和一个偶数,也就是最后一位一定是0。通过这种手段我们就可以计算出结果中的右边有几个0,那么左边是什么呢?左边就应该是n右移i位后剩余的部分。

class Solution:
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        i = 0
        while m != n:
            m >>= 1
            n >>= 1
            i += 1
        return n << i

实际上我们右边有多少个0是可以计算出来的。我们只需要计算m^n后,然后获取从右往左最后一个1的位置i,,这个位置就是我们需要左移的位置。我们可以通过 i n t ( l o g 2 m n ) + 1 int(log_2^{m\oplus n})+1 计算得到位置,在python中,我们直接使用bit_length即可。

class Solution:
    def rangeBitwiseAnd(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        i = (m ^ n).bit_length()
        return m >> i << i

是不是很酷。

reference:

https://leetcode.com/problems/bitwise-and-of-numbers-range/discuss/56729/Bit-operation-solution(JAVA)

https://leetcode.com/problems/bitwise-and-of-numbers-range/discuss/56863/A-Math-solution.

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/86064015