【LeetCode】006 Bitwise AND of Numbers Range 区间内整数按位与

来源:互联网 发布:火眼金睛答题软件使用 编辑:程序博客网 时间:2024/05/29 18:55

【题目】

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 <= m <= n <= 2147483647,将 [m, n] 中所有整数按位进行与运算。

【解析】

思路一:循环

​程序如下:

int rangeBitwiseAnd(int m, int n) {

    while(m

    n &= (n-1);

    return n;

}

​思路二:位移运算

​>> 右移运算符,将二进制数向右移动一位,空位用“0”填充。

<< 左移运算符,​将二进制数向左移动一位,空位用“0”填充。

​1. 奇数和偶数的最后一位相与之后,结果为0;

2. 当m和n不相等的时候,m和n之间一定至少存在一个奇数和一个偶数,因此​最后一位相与之后,结果为0;

3. ​将m和n分别右移一位,开始比较倒数第二位;

4. 重复1—3步,当m=n时,跳出循环。

5.​ 之前右移了x位,在这一步左移回来。达到置0的目的。

为什么只需要将m和n进行与运算,中间的数都可以跳过?

事实上,本题的核心在于,将m和n转化为二进制,若m的位数与n不同,则在m之前补0。然后,从左向右数第一个0开始向右全部置0,得到的数即最终结果。

例:​

​m的第三位为第一次出现的0,则在m和n之间一定存在一个数使得,第三位为1,之后所有位都为0,因此最终结果中,从第三位开始都为0。

​​【程序】

​以下为高票java程序,m和n每右移一位,movefactor左移一位,即在数值上×2,右移x位后,movefactor数值上扩大了2^x倍,最后将m×movefactor,意为将m右移x位。

看看大神的一行代码

其中除以二相当于右移一位,再通过自身的嵌套代替循环。

【关于bug】

若将思路一程序改为如下:​

int rangeBitwiseAnd(int m, int n) {

    while(m

   m &= (m+1);

    return m;

}

则会出错,讲道理从后往前和从前往后不一样么……

​因为进行相与运算的时候,数字总会比原来小(除非两个数相同),因此思路一中将n-1带入下一次运算,跳过了其中许多步计算,简化计算。而本bug中,相与运算后m变小无法通过+1将循环继续下去,因此困在循环当中无法跳出。

0 0