奇妙的位运算(二)

上篇的链接为:http://www.cnblogs.com/jiu0821/p/4677184.html

这次是偶然看到一个题目,很好玩,便记在这里吧!

Bitwise AND of Numbers Range

给出一个范围,[m, n](0 <= m <= n <= 2147483647),返回这些数字的与运算结果。

直接逐个做与运算,TLE,我们得发现高效解法。

我们把[0, 15]用二进制码表示出来:

0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1

仔细看,几个连续的二进制码肯定会有相同的前缀(前缀长度可能为0),除了相同的前缀外,将之后的各位置为0即为所求。如何求解这个相同前缀?只需要m和n同时右移,直到两数相等为止:

 1 class Solution {
 2 public:
 3     int rangeBitwiseAnd(int m, int n) {
 4         int t=0;
 5         while(m!=n){
 6             m>>=1;
 7             n>>=1;
 8             t++;
 9         }
10         return m<<t;
11     }
12 };

或者:

1 class Solution {
2 public:
3     int rangeBitwiseAnd(int m, int n) {
4         if(m==n)    return m;
5         int t=rangeBitwiseAnd(m>>1,n>>1);
6         return t<<1;
7     }
8 };

还有一种更巧妙的方法,将n的最右边的 1 bit 置为0,直到值不大于m即可:

1 class Solution {
2 public:
3     int rangeBitwiseAnd(int m, int n) {
4         while(m<n)  n&=n-1;
5         return n;
6     }
7 };
原文地址:https://www.cnblogs.com/jiu0821/p/4931996.html