LeetCode201 Bitwise AND of Numbers Range

LeetCode201 Bitwise AND of Numbers Range

Description

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.
The signature of the C++ function:int rangeBitwiseAnd(int m, int n)

题解

  • 分析
      最直接的方法:brute force。毫无疑问,经过n - m次与操作,一定可以得到解,时间复杂度O(n - m)。但是,如果n很大,且m远小于n会发生什么情况呢?此时,时间复杂度为O(n)。
      
      Can We Do Better?
      
      先观察与运算的特性,经过一连串的与操作,只要某个位上出现过1次0,在最终的结果中,这个位就必定为0。我们可以从m,通过每次增加1,经过n-m步加1操作,就能得到n。在二进制下观察这n-m步操作,会发现每一步都会有某些位上的数从1变为0,或者从0变为1。而且,变化的位置都集中出现在右端,从某个位置开始,再往左的数位不会发生变化。那些始终不变化的数位,在经过n-m次与操作后,依旧会保持不变。那些曾经出现改变的位,其值必定在某个时刻是0,要么原始值是0,要么原始值是1但是经过变化后变成0,在最后的结果中,这些位必定是0。
      

      这样,我们的任务转化为了如何求出有右端有多少个数位发生了变化。
      在那n-m次加1操作中,可很好地观察到,n-m的二进制表示的位数要么和发生过改变的位的数目相等,要么小1(最后一次加操作有进位)。
      

十进制二进制
100001
200010
300011
400100
500101
600111

核心代码

        int res = 0;
        int bitMask = 2147483647;
        int diff = n - m;
        int bitNum = 0;
        while(diff != 0)
        {
            diff >>= 1;
            ++bitNum;
            bitMask >>= 1;
        }
        bitMask <<= bitNum;
        bitMask &= m;
        res = n & bitMask;

        return res;

时间复杂度:0(1)。while循环最多走32次(只需要log(n-m)次)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值