题目链接:
201. Bitwise AND of Numbers Range
题目大意:
给定整数 m, n 满足 0 <= m <= n <= 2147483647, 求出区间 [m, n] 上所有整数的 与;
例如: 给定 m, n 分别为 5, 7, 则输出应为: 4 (也即 5 & 6 & 7);
解题过程:
(1) 若直接尝试暴力方式, 显然不行, 会超时;
(2) 考虑题意是 "连续的" "与" 运算, 故显然任一运算数的任何一个(二进制形式下的, 下同)位为 0, 则输出结果在这一位上的值也为 0;
(3) 考虑利用给定区间内的 底数为 2 的幂, 因为其形式必然为 100...00; 但是在实现的过程中, 莫名切换思路为: 对输出结果(可以初始化为 n)的进行逐位判断, 显然就这个层面上最多只需要进行 31 轮的判断;
(4) 然后考虑逐位的判断方法, 于是干脆利用对 1 的逐位左移的结果作为掩码, 对样本进行与操作即可; 又知, 不可能将整个区间上的整数作为样本; 所以经考虑, 可以利用 ( x & (trial - 1) ) + 1 作为步进, 其中 x 为样本, trial 为掩码;
代码如下:
int
rangeBitwiseAnd( int m, int n ) {
int min = m;
int max = n;
int ret = max;
int trial = 1;
for ( int i = 0; i < 31 && trial <= max; i++, trial <<= 1 ) {
for ( int x = max; x >= min; x -= ( ( x & ( trial - 1 ) ) + 1 ) ) {
if ( ( x & trial ) == 0 ) {
ret &= ~trial;
break;
}
}
}
return ret;
}
Runtime: 25 ms