您的位置:首页 > 其它

leetcode 201:Bitwise AND of Numbers Range

2015-09-01 19:33 405 查看
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(m<n)
n = n & (n-1);   //n&(n-1)的目的是去掉二进制最右边的1,好比我上面程序的求j那块循环
return n;
}


很明显他这个代码要清晰简洁多了。留作记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: