3133. 数组最后一个元素的最小值
3133. 数组最后一个元素的最小值
题目
You are given two integers n
and x
. You have to construct an array of positive integers nums
of size n
where for every 0 <= i < n - 1
, nums[i + 1]
is greater than nums[i]
, and the result of the bitwise AND
operation between all elements of nums
is x
.
Return the minimum possible value of nums[n - 1]
.
Example 1:
Input: n = 3, x = 4
Output: 6
Explanation:
nums
can be [4,5,6]
and its last element is 6.
Example 2:
Input: n = 2, x = 7
Output: 15
Explanation:
nums
can be [7,15]
and its last element is 15.
Constraints:
1 <= n, x <= 10^8
题目大意
给你两个整数 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 <= 10^8
解题思路
BigInt 处理大数:
- 为了确保算法能处理极大的输入(如
n = 10^8
),需要将n
和x
转换为BigInt
类型,以避免溢出。
- 为了确保算法能处理极大的输入(如
循环遍历位掩码:
- 使用一个位掩码
mask
从1n
(即二进制最低位)开始,每次左移一位,遍历所有位。 - 对于每一位,检查
x
的当前位是否为0
。如果x
在该位为0
,则可以尝试在number
中设置这一位,以确保最后生成的数不影响最终AND
的结果。
- 使用一个位掩码
按条件更新
number
:- 对于每一位:
- 检查
x
的当前位,如果它为0
,则考虑是否将该位设为1
,使得生成的数尽可能大。 - 为此,使用
(n & 1n) * BigInt(mask)
,这在n
的最低位为1
时会将number
的相应位设为1
。 - 然后将
n
右移一位,以检查下一位。
- 检查
- 这样做的结果是,只在
n
指定的某些位置将number
设为更高的值。
- 对于每一位:
转换并返回结果:
- 将最终得到的
number
转换为Number
类型并返回。
- 将最终得到的
复杂度分析
- 时间复杂度:
O(log n)
,因为每次循环中n
右移一位。 - 空间复杂度:
O(1)
,仅使用常数额外空间。
代码
/**
* @param {number} n
* @param {number} x
* @return {number}
*/
var minEnd = function (n, x) {
var number = BigInt(x);
n = BigInt(n) - 1n;
for (var mask = 1n; n > 0n; mask <<= 1n) {
if ((mask & BigInt(x)) == 0n) {
number = number | ((n & 1n) * BigInt(mask));
n >>= 1n;
}
}
return Number(number);
};