[LeetCode] (medium) 201. Bitwise AND of Numbers Range

本文探讨了LeetCode题目中的位运算问题,给出两种算法解决范围[m,n]内所有数字的位与运算。第一种算法通过判断每一位上是否存在为0的可能来求解;第二种算法则寻找m和n的最长相同前缀,利用位运算的性质简化问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://leetcode.com/problems/bitwise-and-of-numbers-range/

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

由于AND的性质,针对某一位,只需要判断在整个范围中的所有数字在这一位上是否存在为0的可能。注意到针对特定位,连续的数字在这一位上表现为连续的0和连续的1,同时连续数字出现的次数从一开始每次翻倍,因此针对某一位i有两种情况:

1、数据的总数超过了当前位的最大连续数字数(1<<i),此时必然存在为0的数

2、数据的总数小于等于最大连续数字数。注意到当前位全为1要求整个数据集中所有数的0~i位均落在[1<<i, 1<<(i+1)-1]这个范围中,由于mn的选择是任意的(不对齐),所以不能简单的通过(mm >= (1<<i) && nn <= 1<<(i+1)-1)进行判断,而是确定底数后加上数据集总数得到“广义上界”再与1<<(i+1)-1进行比较。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        unsigned thre = 1;
        unsigned result = 0;
        unsigned mm = m;
        unsigned nn = n;
        unsigned num = nn-mm+1;
        
        
        for(int i = 0; i < 31; ++i){
            // cout << "i: " << i << endl;
            // cout << "thre: " << thre << endl;
            if(num > thre){
                //do nothing;
            }else{
                unsigned mask = ((unsigned)1<<(i+1))-1;
                unsigned tem = mm & mask;
                // cout << "mask: " << mask << endl;
                // cout << "tem: " << tem << endl;
                if(tem >= (1<<i) && tem+num-1 <= mask){
                    result |= (1 << i);
                }
            }
            thre <<= 1;
        }
        return result;
    }
};

还有另一种算法就是找到m和n的最长相同前缀,这是因为针对任何一个m与n不同的位,有两种情况:

1、m为0,n为1,则从m到n必然会经历(这一位)1000...000(最低位)这一步,则必然均为0。

2、m为1,n为0,同上(因为进位)。

class Solution {
public:
    int rangeBitwiseAnd(int m, int n) {
        int shift=0;
        while(m!=n)
        {
            m>>=1;
            n>>=1;
            shift++;
        }
        return m<<shift;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值