版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[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
,,这个位置就是我们需要左移的位置。我们可以通过
计算得到位置,在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/56863/A-Math-solution.
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!