题目详情
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
示例 1:
输入: [5,7]
输出: 4
示例 2:
输入: [0,1]
输出: 0
——题目难度:中等
分析
直接考虑 m 和 n,如果m一开始就等于n,那直接返回n即可;
如果n = m + 1,假设m的末位是0,那么m的末位就是1,说明两者末尾不相等,通过m和n不断右移,并记录右移的次数(保存在变量count里),找到两者从后往前数的最长公共位(需要从右往左一位对一位,也就是 m == n 时),然后再让n左移count次即可。
所以有一般情况,只要n > m,那么两者的末尾肯定是不相等的,通过m和n不断右移,并记录右移的次数(保存在变量count里),找到两者从后往前数的最长公共位(需要从右往左一位对一位,也就是 m == n 时),说明对于结果数来说 公共位之后因为n 和 m之间的数都是不断 + 1进位(或没进位)所得,那么公共位之后的所有位数都必然经历了 0 和 1 的变化,那么这些数按位与后的结果数 公共位之后的所有位数都必为 0 。最后再让n左移count次即可。n == m也是一样。
-解题代码
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int count = 0;
while (m != n) {
m >>= 1;
n >>= 1;
count++;
}
n <<= count;
return n;
}
};
结果