题目链接:
题目:
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
Example 1:
Input: [5,7] Output: 4
Example 2:
Input: [0,1] Output: 0
题目分析:
给一个区间 [m, n],求区间内所有数的 与运算,输出最后的值。
解题思路:
首先一个思路,枚举暴力,哈哈哈,最后肯定是会超时的,在枚举暴力的时候,要会自己计算一下时间复杂度,这里是 O(n),其中 n 大概是 2^31,而一般一秒认为操作次数大概是 4e+8。
然后要大概分析一下,
比如例子中的 [5, 7]
5:101
6:110
7:111
最后与的结果是 100-->4
可以看出,如果有一个位出现了0,那么该位一定是0
再比如例子:[10, 11]
10:1010
11:1011
最后结果是1010--->12
可以从上面两个例子看出:
如果有0的地方,一定是0
如果出现不同的,即该位又有0,又有1,那么说明,后面的都一定是又有0,又有1,即该为以及后面都会是0
如果出现相同的(无论是0还是1),都要继续往后看
所以最后我们只要从最高位(因为这是int 型的数,最高位为 31)找,如果相同(无论是0还是1),都把这位的0或1存下来。然后继续往后找。如果出现了某一位又有0又有1,那么该位以及后面所有都是0,即跳出循环。
判断一个位置是0还是1,只要将 1<<18,现在令第18位为1 的数,和两个想与运算即可。
那保存下来的0或者1要怎么存进结果,我们将结果初始化为0,如果是1变1,是0变0,所以是一个 或运算。
最后我们分析一下特殊情况,便于程序运行无误且更快。
当最小值为0 时,那就结果为0
如果最大值比最小值大超过2倍,说明最高位就是又有0又有1,那结果就是0。
如果两个数相等,那么返回一样的值。
AC代码:
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
if(m==0 || n/2>=m)
return 0;
if(m==n)
return m;
int res = 0;
int temp;
for(int p = 31;p >= 0;--p)
{
temp = 1<<p;
if((m&temp) == (n&temp))
res |= (m&temp);
else
break;
}
return res;
}
};