您的位置:首页 > 其它

[Leetcode] 201. Bitwise AND of Numbers Range 解题报告

2017-06-14 21:25 791 查看
题目

Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.

For example, given the range [5, 7], you should return 4.
思路

1、循环AND法:我们将返回结果初始化为m,然后从m到n依次与返回结果进行AND运算,并返回结果。这是根据题意最直观想到的解法,属于暴力求解。在Leetcode上无法通过所有测试用例。

2、相邻AND法:可以逐渐将最右边不同的位值置为0,最后只剩下最左边m和n相同的位置。注意到n&(n-1)是将n的最右边的1变为0,所以我们可以不断对n执行n &= (n-1)操作,直到n <= m。这样我们就把m到n之间所有位上值不同的数都置为0了,所以此时n就是需要返回的数值。

3、异位消除法:先求出n - m,然后我们可以根据n - m求出m和n最右边不相同的有多少位,即log(n - m)/log2 + 1位,这也就意味着剩余的左边的位是相同的。所以我们只需要将其左边相同的位数求出来即可。

4、同位保留法:仔细想想就可以发现,题目要求返回的不就是m和n的二进制表示中共同的“左子串”吗?那么我们不断对m和n右移直到两者相等,就巧妙地消除了异位,保留了同位。最后再对m或者n进行左移复原,就巧妙地得到了要求的结果。

有没有发现代码一个比一个精炼效率高?bit manipulation很神奇有木有?

代码

1、循环AND法:

class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int ret = m;
for(int i = m; i <= n; ++i) {
ret &= i;
}
return ret;
}
};2、相邻AND法:
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
while(n > m)
n &= (n - 1);
return n;
}
};
3、异位消除法:

class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int count = log(n-m) / log(2) + 1;
int k = INT_MAX ^ ((1 << count) - 1);
return k & m & n;
}
};
4、同位保留法:

class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int offset = 0;
while(m != n) {
offset++;
m >>= 1;
n >>= 1;
}
return m << offset;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: