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);
};
