「前端刷题」201.数字范围按位与(MEDIUM)

159 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

题目(Bitwise AND of Numbers Range)

链接:https://leetcode-cn.com/problems/bitwise-and-of-numbers-range
解决数:438
通过率:53.5%
标签:位运算 
相关公司:amazon adobe bytedance 

给你两个整数 left 和 right ,表示区间 [left, right] ,返回此区间内所有数字 按位与 的结果(包含 left 、right 端点)。

 

示例 1:

输入: left = 5, right = 7
输出: 4

示例 2:

输入: left = 0, right = 0
输出: 0

示例 3:

输入: left = 1, right = 2147483647
输出: 0

 

提示:

  • 0 <= left <= right <= 231 - 1

思路1

代码

/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */
var rangeBitwiseAnd = function(m, n) {
    if(m == n){   //如果相等返回原值
        return m
    }
    if(m == 0){    //如果有0,返回0
        return 0;
    }
    let res = 0;   //  结果
    let temp = 0;   //   每次要减的数
    while(true){
        let x = m;
        let y = n;
        let count = -1;    // 2的指数
        while(x > 0  && y > 0){
            x = x >> 1;    //右移
            y = y >> 1;
            count++;   //每次右移就说明多了一位
        }
        if(x == 0 && y == 0){    
            temp = 2 ** count;   
            res += temp
        }else{
            return res;
        }
        m -= temp;  
        n -= temp;
    }
    return res;
};

思路2

如果m != n,那么m+1与m最低位一定不同, 也就是最低位相与一定为0,所以可以把m和n的最低位置为0, 如果m和n还不相等,那么m和m + 2相与第二低位也为0,同样可以把m和n 第二低位置为0,以此类推,直到m == n为止

/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */
var rangeBitwiseAnd = function(m, n) {
    let count = 0
    while(m !== n) {
       m >>= 1
       n >>= 1
       count++
    }
    return m << count
};

思路3

主要是针对left和right间距极大的情况,如果这个小于Right的最大2整数次幂大于left,记为pow, 那么pow与大于它的数进行幂运算,都是pow。 pow和小于其的数字进行AND运算,除了left = 1, right = 1这个特殊情况,其他都是0. 总之也是pow & left.

/**
 * @param {number} left
 * @param {number} right
 * @return {number}
 */
 var rangeBitwiseAnd = function(left, right) {
  if (left === 0) return 0;
  const perfectSqRight = findTheLargestPower2(right);
  if (perfectSqRight >= left) return perfectSqRight & left;
  let res = left;
  for (let i = left + 1; i <= right; i++) {
    res = res & i;
  }
  return res;

  function findTheLargestPower2(n) {
    if ((n & -n) === n) return n;
    for (let i = 30; i >= 0; i--) {
      if (n >>> i === 1) return 1 << i;
    }
  }
};

思路4

代码

/**
 * @param {number} left
 * @param {number} right
 * @return {number}
 */
var rangeBitwiseAnd = function(m, n) {
    let shift = 0;
    // 找到公共前缀
    while (m < n) {
        m >>= 1;
        n >>= 1;
        ++shift;
    }
    return m << shift;
};