Leetcode 201 Bitwise AND of Numbers Range

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.

这道题能找到规律之后会变得非常简单。其实规律很简单,只需要找到n和m的二进制表示里第一个不相同的位,然后把之后的数据全部都抹成0即可(包括第一个不相同的位),至于为什么的话,因为从m到n,如果把每个数都与起来,其实也就是会把所有0出现过的位给清掉了,只要出现一次就会清掉。假设二进制表示里第一个不相同的位是t,那么从m到n的过程中,从第0到第t位(从右边数起),每一位都会出现一次0(证明我不在行,我是没找到反例)。
比如说5到7,
总共是3个数:
【5,6,7】
二进制表示分别为:
【101,110,111】
第0位到第1位都有0出现过,所以最终结果会把这两位都清为0,即100,也就是4。
在求n和m第一个不相同的位的时候,我用到了异或运算,还有利用n&(n-1)清最右边的一个1的技巧,具体看代码吧(果然代码就是最好的注释)。

class Solution {
public:
    int getMediaOpVal(int val)
    {
        int nOpVal = 0;
        while(val)
        {
            nOpVal = val;
            val = val & (val - 1);
        }
        nOpVal = (nOpVal << 1) - 1;
        return nOpVal;
    }
    int rangeBitwiseAnd(int m, int n) {
        if(n == m)
            return n;
        int nMedia = m ^ n;
        int nOpVal = getMediaOpVal(nMedia);
        return n & (~nOpVal);
    }
};

查了一下别人的解法,用到的思路是一样的,都是要找到第一个不相同的位,然后清掉后面的值,只不过技巧不同,看起来比我这个更秀气一些,具体代码如下:

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

最后发现这个代码比我自己做的要慢,想了想,确实会如此,我自己的方法关心的是第一个不相同的位之后的1的个数,1的个数比较少的话,那么val&(val-1)会大大加快运算速度,而找到的这个做法不是关心1的个数,而是只关心第一个不相同的位是在什么地方,所以当n和m异或出来的结果1的个数比较稀疏的话,那么我这个方法就会很有优势,如果不是的话,那么基本上效率是差不多的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值