LeetCode 3133.数组最后一个元素的最小值:位运算+双指针

【LetMeFly】3133.数组最后一个元素的最小值:位运算+双指针

力扣题目链接:https://leetcode.cn/problems/minimum-array-end/

给你两个整数 nx 。你需要构造一个长度为 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

解题方法:位运算+双指针

解题思路

所有num与运算的结果为x,说明x二进制下为1的位置在所有num中也全部为1。

那其他位置呢?x二进制下为0的位置呢?当然是可1可0。

因为想要nums数组中最大的那个数尽可能小,所以在填充x非零位置的时候,用从0到 n − 1 n-1 n−1的二进制填充就好了。这样得到的nums数组即为最优。

总之:将 n − 1 n-1 n−1的二进制插入到 x x x中为0的位置即可。

假如 x = 5 ( 101 ) x=5(101) x=5(101),那么x中为0的位有:第2位、第4位、第5位、第6位、...。

假设 n = 3 n=3 n=3,那么 0 0 0到 n − 1 n-1 n−1的2进制为 00 00 00、 01 01 01、 10 10 10。

将这些数填充到x中为0的位置,即可得到nums数组:0 10 1、0 11 1、1 101(加粗的位置是x中为0的位置,填入了0到2这3个数)。

因此 n u m s nums nums中最大的数为:将 n − 1 n-1 n−1的二进制填入 x x x二进制下为 0 0 0的位置。

具体做法

由于 1 ≤ n ≤ 1 0 8 ≤ 2 27 1\leq n\leq 10^8 \le 2^{27} 1≤n≤108≤227,所以只需要考虑 n − 1 n-1 n−1的低 27 27 27位即可。

使用两个指针,ix指向x的每一位,in指向n的每一位。

主循环令in从0到26(指向n的每一位),每次ix找到一个x为0的位(当ix指向的那一位为1时,ix增加1移动到下一位),将这一位赋值为in所指的位的值。

  • 取出x的第ix位:(x >> ix) & 1
  • 取出n的第in位:(n >> in) & 1
  • 构造第in位为n的第in位,其余位为0的数:(n >> in) & 1) << ix
  • 将x的第ix位赋值为n的第in位:x |= (((n >> in) & 1) << ix)

时空复杂度分析

  • 时间复杂度 O ( C ) O(C) O(C),其中 C = log ⁡ ( max ⁡ { n , x } ) = 27 C=\log(\max\{n, x\})=27 C=log(max{n,x})=27
  • 空间复杂度 O ( 1 ) O(1) O(1)

AC代码

C++
cpp 复制代码
/*
将x每个0的位置设置为n-1的二进制
*/
typedef long long ll;

class Solution {
public:
    ll minEnd(ll n, ll x) {
        n--;
        for (int in = 0, ix = 0; in < 27; in++, ix++) {
            while ((x >> ix) & 1) {  // 找到下一个为0的位置
                ix++;
            }
            x |= (((n >> in) & 1) << ix);
        }
        return x;
    }
};
Go
go 复制代码
package main

func minEnd(n int, x int) int64 {
    n64, ans := (int64)(n - 1), (int64)(x)
    for in, ix := 0, 0; in < 27; in, ix = in + 1, ix + 1 {
        for ((ans >> ix) & 1) != 0 {
            ix++
        }
        ans |= (((n64 >> in) & 1) << ix)
    }
    return ans
}
Java
java 复制代码
class Solution {
    public long minEnd(long n, long x) {
        n--;
        for (int in = 0, ix = 0; in < 27; in++, ix++) {
            while (((x >> ix) & 1) != 0) {
                ix++;
            }
            x |= (((n >> in) & 1) << ix);
        }
        return x;
    }
}
Python
python 复制代码
class Solution:
    def minEnd(self, n: int, x: int) -> int:
        n -= 1
        ix = 0
        for in_ in range(27):
            while (x >> ix) & 1:
                ix += 1
            x |= (((n >> in_) & 1) << ix)
            ix += 1
        return x

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/141440484

相关推荐
m0_737539372 分钟前
pod Scheduler调度
算法·贪心算法
此生决int11 分钟前
算法从入门到精通——双指针
算法
普马萨特24 分钟前
Uber H3:地理网格索引在空间数据分析中的应用
数据结构·算法
alphaTao28 分钟前
LeetCode 每日一题 2026/5/11-2026/5/17
算法·leetcode
洛水水29 分钟前
【力扣100题】45.零钱兑换
算法·leetcode·职场和发展
Aaron15881 小时前
全频段 SDR干扰源模块解决方案(星链干扰、LORA无人机干扰)
人工智能·算法·fpga开发·硬件架构·硬件工程·无人机·信息与通信
AI科技星1 小时前
全域数学·球面拓扑微扰标准系数η=0.01 应用详解(典籍正式版)
人工智能·算法·数学建模·数据挖掘·机器人
逻辑君1 小时前
物理学研究报告【20260001】
人工智能·算法
YL200404261 小时前
041二叉树的层序遍历
数据结构·leetcode·bfs
AI科技星1 小时前
算法联盟·全域数学公理体系下黑洞标量毛发与LVK引力波O4全维理论、求导、证明、计算、验证、分析
人工智能·线性代数·算法·架构·学习方法·量子计算