LeetCode-Python-3133. 数组最后一个元素的最小值(位运算)

给你两个整数 n 和 x 。你需要构造一个长度为 n 的 正整数 数组 nums ,对于所有 0 <= i < n - 1 ,满足 nums[i + 1] 大于 nums[i] ,并且数组 nums 中所有元素的按位 AND 运算结果为 x 。

返回 nums[n - 1] 可能的 最小 值。

示例 1:

输入:n = 3, x = 4

输出:6

解释:

数组 nums 可以是 [4,5,6] ,最后一个元素为 6 。

示例 2:

输入:n = 2, x = 7

输出:15

解释:

数组 nums 可以是 [7,15] ,最后一个元素为 15 。

提示:

  • 1 <= n, x <= 108

思路:

根据题意,数组里第一个数必定是 x, 其他的数的二进制除了 x 以外的AND运算结果应该为0。

我们不妨从简单的数字开始考虑,比如当 x = 111,即 7 的时候,

下一个满足题意的数字应该是 1111,

接着是 10111, 11111, 100111, 可以观察到这个不同的部分其实就是 1, 2, 3..的二进制。

接着当 x = 100, 即 4 的时候,

我们可以得到接下来的数字有: 101, 110, 111, 1100,和之前一样新加上去的部分也是1, 2, 3, 4...

所以不难发现,题目所要求的答案就是把 n - 1 的二进制,跟 x 结合在一起。

结合的方法是,从右往左,当 x 的二进制上出现 0 的时候,我们就把 n - 1 二进制的一位放进去。

时间复杂度:O(logx + logn)

空间复杂度:O(logx + logn)

class Solution:
    def minEnd(self, n: int, x: int) -> int:
        #  01bin(x) -> 10bin(x) -> 11bin(x) -> 100bin(x) -> 101bin(x)
        digits = [digit for digit in bin(x)[2:]]

        to_be_inserted = bin(n - 1)[2:]
        # print(to_be_inserted)
        pos = len(to_be_inserted)
        for i in range(len(digits) - 1, -1, -1):
            if digits[i] == "0":
                pos -= 1
                digits[i] = to_be_inserted[pos]
            if pos == 0:
                break
        
        return int(to_be_inserted[:pos] + "".join([digit for digit in digits]), 2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值