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

devtools/2024/12/22 3:00:56/

【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 n1二进制填充就好了。这样得到的nums数组即为最优。

总之:将 n − 1 n-1 n1二进制插入到 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 n1的2进制为 00 00 00 01 01 01 10 10 10

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

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

具体做法

由于 1 ≤ n ≤ 1 0 8 ≤ 2 27 1\leq n\leq 10^8 \le 2^{27} 1n108227,所以只需要考虑 n − 1 n-1 n1的低 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++
/*
将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
package mainfunc 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
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
class Solution:def minEnd(self, n: int, x: int) -> int:n -= 1ix = 0for in_ in range(27):while (x >> ix) & 1:ix += 1x |= (((n >> in_) & 1) << ix)ix += 1return x

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

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


http://www.ppmy.cn/devtools/101921.html

相关文章

网络游戏运营

游戏运营是将一款游戏平台推入市场&#xff0c;并通过一系列的策略和行动&#xff0c;使玩家从接触、认识到最终成为忠实玩家的过程。这一过程涵盖了多个方面&#xff0c;包括前期准备、上线运营、活动策划、数据分析、渠道合作以及用户维护等。以下是对游戏运营的详细解析&…

用ChatGPT精确营销:如何让AI深度理解并推广你的产品

在现代商业中,人工智能(AI)正迅速成为企业成功的关键因素之一。ChatGPT作为一种强大的语言模型,不仅能回答问题,还能通过深度理解和互动,帮助企业精准推广产品。然而,如何让ChatGPT真正了解并有效地推广你的产品,是许多使用者面临的挑战。在本文中,我们将探讨如何通过…

debian/ubuntu 通过串口连接WiFi

修改 /etc/wpa_supplicant.conf&#xff0c;如果没有这个文件就创建文件 vi /etc/wpa_supplicant.conf设置wifi信息 network{ssid"这里是你的wifi账号"psk"这里是你的wifi密码" }连接wifi killall wpa_supplicant wpa_supplicant -i wlan0 -c /etc/wpa_…

SQLite 插入数据并返回自增ID

要插入数据并返回自增ID&#xff0c;我们可以使用SQLite的last_insert_rowid()函数。这个函数返回了最后一次插入操作的自增ID。 下面我们通过一个示例来演示如何插入数据并返回自增ID。 首先&#xff0c;创建一个表来存储学生信息&#xff1a; CREATE TABLE students (id I…

【研究生论文】—— 综述怎么写

怎么写综述 “综述”指的是对某一特定主题或领域h的文献、研究、进展等进行系统性回顾和总结的一种文章类型。很多时候我们需要知道的不是综述是什么&#xff0c;而是综述不是什么&#xff0c;综述不是单纯的查询报告&#xff0c;综述需要在自己的查询结果上面提出自己的看法和…

5个常见问答 | 1+X证书《大数据应用开发(Python)》

1、 1X大数据应用开发&#xff08;Python&#xff09;哪些人群可以考&#xff1f; 全日制在读的中高职学校、应用型本科、本科层次职业教育试点学校院校的学生&#xff0c;有意向从事与证书相关岗位的社会人士都可考取该证书。 2、1X大数据应用开发&#xff08;Python&am…

etcd参数解释

etcd 版本 [rootaaaaaa ~]# /data/etcd/etcd-v3.5.15-linux-amd64/etcd --version etcd Version: 3.5.15 Git SHA: 9a5533382 Go Version: go1.21.12 Go OS/Arch: linux/amd64基础命令: etcd [flags]&#xff1a;启动一个 etcd 服务器。etcd --version&#xff1a;显示 etcd…

仿Muduo库实现高并发服务器——LoopThreadPool模块

这个模块需要具备那些基础知识。 线程创建相关操作&#xff0c;锁&#xff0c;条件变量。 设置线程数量&#xff1a; _thread_count 是线程池中&#xff0c;记录线程数量的成员。 创建线程池&#xff1a; 上图就是线程池的创建&#xff0c;将线程与EventLoop对象 通过数组下…