📜  范围 [L, R] 中两个数字的最大可能按位或(1)

📅  最后修改于: 2023-12-03 15:11:50.011000             🧑  作者: Mango

求范围 [L, R] 中两个数字的最大可能按位或

问题描述

给定两个整数 L 和 R,找到范围 [L, R](含 L 和 R)中两个数字的最大可能按位或,返回按位或的结果。

解决方法
算法一

首先可以看到题目要求我们在一个范围内找到两个数的按位或的最大值,因此可以考虑对于每一位来选择 1,这样可以得到该范围内的最大值。

  • 从高到低考虑每一位,假设当前考虑到第 i 位。
    • 如果 L 和 R 在第 i 位的值不同,那么这一位以上的值都可以选择为 1。
    • 如果 L 和 R 在第 i 位的值相同,那么这一位的值只能选择对应的值。
算法二

另一种思路是对于 L 和 R 的二进制表示,从高位到低位,将剩余位数全部补成 1,并根据按位或的性质,最终的结果一定是 L 和 R 按位或结果的前缀。

具体算法如下:

  1. 对 L 和 R 按位或,得到按位或的结果 M;
  2. 观察 M 的二进制表示,将 M 右移,直到得到的二进制数和 L 相同,并记录移位数;
  3. 最终的结果即为 L 左移移位数之后的结果。

这个算法虽然看起来比较简单,但是却需要使用位运算和位移这一类的技巧。

代码实现
算法一代码
def max_or_num(L: int, R: int) -> int:
    res, k = 0, 0
    while L or R:
        if L & 1 == R & 1:
            res += (L & 1) << k
        else:
            res = ((1 << (k + 1)) - 1)
        k += 1
        L >>= 1
        R >>= 1
    return res

算法二代码
def max_or_num(L: int, R: int) -> int:
    M = L | R
    k = 0
    while M > L:
        M >>= 1
        k += 1
    return L | (1 << k) - 1

总结

本文介绍了两种不同的算法来解决范围 [L, R] 中两个数字的最大可能按位或的问题,分别是暴力枚举和位运算。算法一相对容易理解,时间复杂度为 $O(\log_2 R)$,而算法二则需要一些位运算和位移的技巧,时间复杂度为 $O(1)$。对于这道题目,采用不同的算法可以得到不同的思考方式,给程序员提供了一定的挑战。