3314. 构造最小位运算数组 I
给你一个长度为 n
的质数数组 nums
。你的任务是返回一个长度为 n
的数组 ans
,对于每个下标 i
,以下 条件 均成立:
ans[i] OR (ans[i] + 1) == nums[i]
除此以外,你需要 最小化 结果数组里每一个 ans[i]
。
如果没法找到符合 条件 的 ans[i]
,那么 ans[i] = -1
。
质数 指的是一个大于 1 的自然数,且它只有 1 和自己两个因数。
示例 1:
输入:nums = [2,3,5,7]
输出:[-1,1,4,3]
解释:
对于
i = 0
,不存在ans[0]
满足ans[0] OR (ans[0] + 1) = 2
,所以ans[0] = -1
。对于
i = 1
,满足ans[1] OR (ans[1] + 1) = 3
的最小ans[1]
为1
,因为1 OR (1 + 1) = 3
。对于
i = 2
,满足ans[2] OR (ans[2] + 1) = 5
的最小ans[2]
为4
,因为4 OR (4 + 1) = 5
。对于
i = 3
,满足ans[3] OR (ans[3] + 1) = 7
的最小ans[3]
为3
,因为3 OR (3 + 1) = 7
。
示例 2:
输入:nums = [11,13,31]
输出:[9,12,15]
解释:
对于
i = 0
,满足ans[0] OR (ans[0] + 1) = 11
的最小ans[0]
为9
,因为9 OR (9 + 1) = 11
。对于
i = 1
,满足ans[1] OR (ans[1] + 1) = 13
的最小ans[1]
为12
,因为12 OR (12 + 1) = 13
。对于
i = 2
,满足ans[2] OR (ans[2] + 1) = 31
的最小ans[2]
为15
,因为15 OR (15 + 1) = 31
。
提示:
1 <= nums.length <= 100
2 <= nums[i] <= 1000
nums[i]
是一个质数。
思路
数学
ans[i] OR (ans[i] + 1)
必为奇数是质数的偶数只有2,且无结果,即 num[i]=2时,ans[i]=-1
设
s = nums[i] + 1
,并令v
为s
的二进制表示中最低位 1 的位置(即s
可被2^V整除,但不能被2^{V+1}整除)。则满足条件的最小ans[i]
为nums[i]-2^{v-1}。推导依据:通过分析
x OR (x + 1)
的二进制性质,可得x | (x + 1) = (y + 1) \cdot 2^k - 1,其中k
是某个正整数。令其等于质数p
,则p + 1 = (y + 1) \cdot 2^k。因此,p + 1
必须被某个2^K整除。最小x
对应于最大的k
(即k = v
),此时x=p-2^{v-1}。计算方式:使用位运算高效计算:
lsb = s & -s
:得到s
的最低有效位(即2^v)。(一个字:绝)power = lsb >> 1
:得到 2^{v-1}(因为lsb
是 2^v,右移一位得到 2^{v-1})。ans[i] = nums[i] - power
。
代码
数学
class Solution {
public int[] minBitwiseArray(List<Integer> nums) {
int[] result = new int[nums.size()];
int index = 0;
for (int p : nums) {
if (p == 2) {
result[index] = -1;
} else {
int s = p + 1;
int lsb = s & -s; // 获取最低有效位
int power = lsb >> 1; // 计算2^{k-1}
result[index] = p - power; // 计算答案
}
index++;
}
return result;
}
}