解法1
最通俗的解法,区间的两端,在不相等的情况下,区间之内最后一位与运算之后一定是0,这样的话,每次都让m,n向右移动,知道m和n相等即可
public static int rangeBitwiseAnd(int m, int n) { int count=0; //只要m<n表明这个位置就可以置为0,也就是最后一位可以置为0 while(m<n) { count++; m>>>=1; n>>>=1; } return m<<count; }
解法2
通过解法1,我们已经了解了这道题的本质了,就是不断的考虑最后一位,只要当前m<n,我们就可以把n的最后一位置为0。
将当前数字的最后一位置为0,n=n&(n-1)
public static int rangeBitwiseAnd2(int m, int n) { while(m<n) { n=n&(n-1); } return n; }
解法3
上述的两种解法都是从右向左考虑的,我们现在可以从左向右考虑,从第一位不相同的位开始考虑
public static int rangeBitwiseAnd3(int m, int n) { if(m==n){ return m; } return m&(~Integer.highestOneBit(m^n)+1); }
Integer.highestOneBit这个方法就是保留最高位的1,其他的位全部置为0,取反加1就是去相反数
public static int highestOneBit(int i) { // HD, Figure 3-1 i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1); }
return之前的操作就是将最高位以及最高位右边的数字全部置为1,然后将当前的数字向右移动,相减就可以得到结果