给你一个长度为 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 <= 1002 <= nums[i] <= 10^9nums[i]是一个质数。
分析:x+1 在二进制上是把 x 最低位 0 的右边所有的 1 变成 0,再把最低位的 0 变成 1,由此可得 x OR (x+1) 就是把 x 最低位的 0 变成 1,这个值一定是一个奇数。由于 nums 数组元素都是质数,当 nums[i] 为 2 时一定无解,对应的 ans[i] 等于 -1;其它奇数质数的情况时,从低位向高位找到连续的最高位的 1,把这个位置的 1 变成 0 即为答案。
举例:设 nums[i] 的二进制为 00010111,对应的答案为 00010011。算法为:遇到 0 之前,从低位向高位找到连续的最高位 1,把这一位变成 0.
cpp
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* minBitwiseArray(int* nums, int numsSize, int* returnSize) {
int *ans=(int*)malloc(sizeof(int)*numsSize);
*returnSize=numsSize;
for(int i=0;i<numsSize;++i)
{
if(nums[i]==2)ans[i]=-1;
else
{
int temp=nums[i],cnt=1;ans[i]=nums[i];
while(temp&1)
cnt*=2,temp>>=1;
ans[i]-=cnt/2;
}
}
return ans;
}