LeetCode 201. 数字范围按位与

发布于 2023-06-03 17:49:41 字数 2026 浏览 47 评论 0

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

示例 1:

输入: [5,7]
输出: 4
示例 2:

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

前置知识

  • 位运算

公司

  • 阿里
  • 腾讯
  • 百度
  • 字节

思路

一个显而易见的解法是, 从 m 到 n 依次进行求与的操作。

let res = m;
for (let i = m + 1; i <= n; i++) {
  res = res & i;
}
return res;

但是, 如果你把这个 solution 提交的话,很显然不会通过, 会超时。

我们依旧还是用 trick 来简化操作。 我们利用的性质是, n 个连续数字求与的时候,前 m 位都是 1.

举题目给的例子:[5,7] 共 5, 6,7 三个数字, 用二进制表示 101, 110,111, 这三个数字特点是第一位都是 1,后面几位求与一定是 0.

再来一个明显的例子:[20, 24], 共 20, 21, 22, 23,24 五个数字,二进制表示就是

0001 0100
0001 0101
0001 0110
0001 0111
0001 1000

这五个数字特点是第四位都是 1,后面几位求与一定是 0.

因此我们的思路就是, 求出这个数字区间的数字前多少位都是 1 了,那么他们求与的结果一定是前几位数字,然后后面都是 0.

关键点解析

  • n 个连续数字求与的时候,前 m 位都是 1

  • 可以用递归实现, 个人认为比较难想到

  • bit 运算

代码:

n > m ? rangeBitwiseAnd(m / 2, n / 2) << 1 : m;

每次问题规模缩小一半, 这是二分法吗?

代码

语言支持:JavaSCript,Python3

JavaScript Code:

/*
 * @lc app=leetcode id=201 lang=javascript
 *
 * [201] Bitwise AND of Numbers Range
 *
 */
/**
 * @param {number} m
 * @param {number} n
 * @return {number}
 */
var rangeBitwiseAnd = function (m, n) {
  let count = 0;
  while (m !== n) {
    m = m >> 1;
    n = n >> 1;
    count++;
  }

  return n << count;
};

Python Code:

class Solution:
    def rangeBitwiseAnd(self, m: int, n: int) -> int:
        cnt = 0
        while m != n:
            m >>= 1
            n >>= 1
            cnt += 1

        return m << cnt

复杂度分析

  • 时间复杂度:最坏的情况我们需要循环 N 次,最好的情况是一次都不需要, 因此时间复杂度取决于我们移动的位数,具体移动的次数取决于我们的输入,平均来说时间复杂度为 $O(N)$,其中 N 为 M 和 N 的二进制表示的位数。
  • 空间复杂度:$O(1)$

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

骄兵必败

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

13886483628

文章 0 评论 0

流年已逝

文章 0 评论 0

℡寂寞咖啡

文章 0 评论 0

笑看君怀她人

文章 0 评论 0

wkeithbarry

文章 0 评论 0

素手挽清风

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文