Leetcode-201- Bitwise AND of Numbers Range

来源:互联网 发布:vb怎么添加下拉菜单 编辑:程序博客网 时间:2024/06/03 13:03

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. 

题意:m到n若干个数字按位与运算的最后结果,比如5-7,写成2进制分别是0101,0110,0111与运算后得到0100,结果为4。

解析:理解了提议之后,就可以立马想到一个暴力破解的方法,直接从m与运算到n就得了呗,超时归超时,但是这是最简单的办法。

撇开这个暴力的方法,这个题有两个思路可以解开。

思路一:从前面开始找,假设m=3,比它小的最大的2的乘方是2,n=9,比它大的最小的2的乘方是8,可以得出什么结论呢?3(0011)=0010+0001,9(1000)=1000+0001;那么3到9的bitwise and 结果就是0,为什么?3的最高位为1的位数是左起第三位,9 是左起第1位,3到9中间有个8,在与8的时候后面3位都是0,在与3的时候前面两位都是0,这样一综合的看,4位全是0。因此可以这么认为:当m,n取以2为底的对数时,如果得到的结果去下整不相同,则结果为0。那么当结果取下整相同的时候怎么办呢,比如5,7取对数后的下整是2,则结果最小也是2的2次方,然后我们将m,n同时减去2的2次方后重复以上过程,就可以得到最后的结果。(这个思路比较好理解,但是代码实现起来比较繁琐,这里我就贴一下我的视线方法,虽然也ac了,但是确实很慢)。

代码实现:

 public class Solution    {        public int RangeBitwiseAnd(int m, int n)        {            if (m == 0)                return 0;            int ret = 0;            while (m != 0 && n != 0)            {                int k = (int)Math.Floor(Math.Log(m, 2));                int b = (int)Math.Floor(Math.Log(n, 2));                if (k < b)                    return ret;                int tmp = (int)Math.Pow(2, k);                ret += tmp;                m -= tmp;                n -= tmp;            }            return ret;        }    }


思路二:从后面开始找,m=0,或者m=n的情况就不说了,当m!=n时,n>=m+1,那么m&(m+1)会有什么结果呢,最后一位一定为0,此时我们就可以忽略掉最后一位,将m>>1,n>>1;新得到的m,n再去判断是否相同,如果m=n,那么此时m&n的结果就是m,但是之前有右移一位的操作,所以最后的结果要左移一位,如果m!=n重复以上的操作,直到m=n(最后m=n=0)。

代码实现:

public static int rangeBitwiseAnd(int m, int n) {int count=0;while(m!=n){m=m>>>1;n=n>>>1;count++;}return m<<count;            }


0 0
原创粉丝点击