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]之间所有数的按位与
初看之下,觉得太简单不过了,直接依次遍历
public class Solution {public int rangeBitwiseAnd(int m, int n) {int tmp = 0xFFFFFFFF;for(int i = m;i < n;i++){tmp &= i;}return tmp&n;}}结果超时。
然后继续改进,怎么能够改进呢?
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
求这些数的按位与,是否可以看出一些规律呢?
1、有0的话,则结果为0
2、假设m<= 2^k,n>=2^(k+1),结果为0,这个可以迅速判断出来结果
3、如果2^(k-1)<=m,n<=2^k,结果为[m,n]之间的所有数的按位与。
public class Solution {public int rangeBitwiseAnd(int m, int n) {if(m == 0){//m为0,结果一定是0return 0;}long tmp = 1;//2^0,注意定义成long型,否则会出现超时,因为0x80000000<0xFFFFFFFFF,但是继续右移会回到0的情况而出现死循环,故定义成long来避免这个情况while(tmp <= m){tmp <<= 1;//2^k}//m<=2^k && m<2^(k+1)if(n >= tmp){return 0;//n>=2^(k+1)}else{int result = m & n;int i = m + 1, j = n – 1;while(i < n && j > m){//采用折半计算,进一步加快求解速度if(i == j){result = result & i;i++;j–;}else{result = result & i & j;i++;j–;}}return result;}}}时间依然有点慢,位于下游,改成c之后就到了c的平均水平。
查看下别人的,取取经:
public class Solution {public int rangeBitwiseAnd(int m, int n) {int offset = 0;while (m!=0 && n!=0){if (m == n){return m << offset;}m >>= 1;n >>= 1;offset++;}return 0;}}观察发现,这个范围的按位与只与m,n的有多少高位是依次相等的,
public class Solution {public int rangeBitwiseAnd(int m, int n) {int offset = 0;while (m!=0 && n!=0){if (m == n){return m << offset;}m >>= 1;n >>= 1;offset++;}return 0;}}简单易懂的代码,相比之下,,自己的代码就是太繁琐了,太多的判断语句,显得杂乱
看着书里九万五千公里的绚丽。又或是和我一样,