您的位置:首页 > 其它

LeetCode201 Bitwise AND of Numbers Range

2015-04-30 11:26 471 查看

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)次)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode math