码迷,mamicode.com
首页 > 其他好文 > 详细

Bitwise AND of Numbers Range -- leetcode

时间:2015-07-12 09:49:18      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:leetcode   位运算   

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.


算法一:使用异或

一个范围内所有的数作位与运算,结果是高位相同部分保存不变,低位为0.

我们要做的是,如何求出这个分界位置。

不需要对范围中每个数,作位与运算,仅需对两个端点作异或运算。

异或运算是,相同位将为0,不同位则为1.

对异或运算结果,从左向右,找到第一个为1的位置。则此位置,为变和不变的分界点。自此位置往右,将是变化部分。在与运算的结果将为0.

然后从此位置将右边的部分全部置为1.  最后取反,即得到掩码。


在将右边位置填充为1的思路为,将其向右移1位,再和自己作或运算。此时,完成向右填充了1位。现在已经有连续2位肯定为1了。

故可以再往右移2位,与自己作或运算。至此完成填充4个bit位。


通过范围的端点,求出左边第一个相异位置,而不需要对每个数进行运算,原因如下:

通过端点求出的左边不变化bit位中,如果对其中一位作一下变动(取反),则得到的新数,将不在这两个端点的范围内。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int mask = m ^ n;
        mask |= mask >> 1;
        mask |= mask >> 2;
        mask |= mask >> 4;
        mask |= mask >> 8;
        mask |= mask >> 16;
            
        return m & ~mask;
    }
};


也可以不填充过程写成循环。但要注意的事,对32位的整数右移右移32位时,结果是未定义的,而不是0.

在leetcode中,右移32位,竟然返回的是1.

故需要在循环加个退出条件:shifts < 32。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int mask = m ^ n;
        int shifts = 1;
        while (shifts < 32 && mask >> shifts) {
            mask |= mask >> shifts;
            shifts <<= 1;
        }
            
        return m & ~mask;
    }
};


算法二,使用掩码偿试

寻找左边第一个开始相异的位置,可以用码码逐位进行偿试。直到相等为止。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int mask = -1;
        while ((m & mask) != (n & mask))
            mask <<= 1;
        
        return m & mask;
    }
};


算法三,同时相右移位

同时相右移位,将不相等位移掉。直到相等。最后向左移位恢复。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int shifts = 0;
        while (m != n) {
            m >>= 1;
            n >>= 1;
            ++shifts;
        }
        
        return m << shifts;
    }
};

写成递归则为:

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        return n != m ? rangeBitwiseAnd(m>>1, n>>1) << 1 : n;
    }
};



版权声明:本文为博主原创文章,未经博主允许不得转载。

Bitwise AND of Numbers Range -- leetcode

标签:leetcode   位运算   

原文地址:http://blog.csdn.net/elton_xiao/article/details/46843751

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!