leetcode 201:Bitwise AND of Numbers Range

Question:
  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。求[m,n](包括m和n)之间所有整数的的结果.

最开始想到的是直接遍历m到n就行了。因为想到的是计算机对操作的话很快的,那么估计不会太耗时。但是真正提交代码的时候发现timeout,真实too young too simple.想想也不可能题目这么水就过了。然后想到的是优化,我们考虑第一个数m,对于与操作的话其实只要考虑1的位就行了,因为0的位肯定还是为0。比如说:
52:00110100
56:00111000
也就是说52和53,54,55与的结果是不变的,这样就不用和中间这几个数进行与操作了。如果数很大的话中间可以跳过很多的数。直接上代码:

int rangeBitwiseAnd(int m, int n)
{
    int res = m;
    int flag = m;
    for(int i=m; i<=n;)
    {
        res = res & i;
        bitset<32> first(res);
        if(0 == res)
            return res;

        //j的目的是为了得到二进制最右边的1
        int j=0;
        while(first[j] == 0)
        {
            j++;
        }

        flag = i;
        //pow(2,j)直接加到下一个影响与结果的数.好比上面例子的52直接加到56,直接跳过中间的53 54 55
        i = i + (int)pow(2, j);

        //这里需要注意的是int类型可能加到有符号整形正数最大的时候,再加的话会变成负数。这时候应该跳出循环
        if(i < 0) break;
    }

    //剩下的数与以下得到最终结果
    for(int i=flag; i<=n; i++)
    {
        if(i < 0) break;
        res = res & i;
    }
    return res;
}

通过测试。
之后看了DISCUSS版,发现一个人的思想和我的是一样的,但是代码非常精简,学习一下:

 int rangeBitwiseAnd(int m, int n) 
 {
     while(m1);   //n&(n-1)的目的是去掉二进制最右边的1,好比我上面程序的求j那块循环
     return n;
 }

很明显他这个代码要清晰简洁多了。留作记录。

你可能感兴趣的:(各类OJ)