LeetCode 数字范围按位与

给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。

示例 1:

输入: [5,7]
输出: 4

示例 2:

输入: [0,1]
输出: 0

思路分析:
在这里插入图片描述
不难发现,只有当区间[m,n]中所有的数字的某一为都为1时,对应的结果这一位才能为1,所以我们统计区间每个数的每一位即可。(时间复杂度O(n - m),额外的空间复杂度O(1))

class Solution {
public:
	int rangeBitwiseAnd(int m, int n) {
		int result = 0, bitCnt = 0, tempValue = 1;
        //对区间的每个数分别进行32位检测
		while (bitCnt < 32) {
			tempValue = (1 << bitCnt);
			//检测[m,n]区间中各个数第bitCnt位是否为零,如果一致都为1,说明result这1位也为1,否则为零
			long long num = m;
			for (; num <= n; ++num) {
				if ((tempValue & num) == 0) {//这个num的第bitCnt位为零(从低到高数)
					break;
				}
			}
			if (num > n) {//如果通过了所有测试,说明[m,n]区间第bitCnt都为1
				result ^= tempValue;
			}
			bitCnt += 1;
		}
		return result;
	}
};

在这里插入图片描述
方法二:当一个数与这个数+1进行按位后,这个数的某一位后面的1将会全部置零。
比如:
在这里插入图片描述
当(m,m+1,…n-1,n)进行连续“与操作”时,会按照上述规律被抵消很大一部分,而只剩下n的前缀部分,最后只需将n归位。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int offset = 0;//标记移动的位数
        //一直右移,直到相等
        while(m != n){
            m >>= 1;
            n >>= 1;
            offset += 1;
        }
        //最后需要往左移回去
        return n << offset;
    }
};

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/88031829