1. 问题背景与核心挑战
这道LeetCode题目属于位运算系列中的经典问题,要求我们构造一个满足特定条件的最小数组。题目给出一个质数数组nums,要求返回一个数组ans,使得对于每个下标i,满足ans[i] OR (ans[i] + 1) == nums[i],并且在所有可能的解中选择最小的ans[i]。
这个问题的难点在于理解位运算OR的特性以及如何逆向推导出满足条件的最小数值。在实际编程面试中,这类位运算问题经常出现,因为它能很好地考察候选人对二进制操作的理解和数学思维能力。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 位运算基础与问题分析
2.1 OR运算的特性分析
OR运算(|)是位运算中的基本操作之一,它对两个数的每一位进行逻辑或运算。关键特性包括:
- 任何数与自身OR结果为自身:x | x = x
- 任何数与0 OR结果为原数:x | 0 = x
- 运算满足交换律和结合律
在本题中,我们需要特别关注x OR (x+1)的特殊性质。这个表达式的结果会将x二进制表示中最右边的0变为1,并将该位右侧的所有1变为0。
2.2 问题转化与逆向思维
题目要求我们找到满足x | (x+1) = nums[i]的最小x。我们可以将这个问题转化为:
- 给定nums[i],找出所有可能的x使得x | (x+1) = nums[i]
- 在这些x中选择最小的一个
通过观察我们可以发现,x | (x+1)的结果总是会将x的最右边的0变为1。因此,我们可以逆向思考:给定nums[i],如何恢复出原始的x。
3. 算法设计与实现细节
3.1 关键思路解析
核心算法思路可以分为以下几个步骤:
-
检查特殊情况:如果nums[i] == 2(唯一的偶质数),直接返回-1,因为x | (x+1)的结果最低位必须是1。
-
对于其他质数:
- 计算nums[i]的按位取反:t = ~nums[i]
- 找到t的最低位1(lowbit):lowbit = t & -t
- 将lowbit右移一位得到掩码
- 将nums[i]与该掩码异或得到结果
这个方法的数学依据是:x | (x+1)的结果中,最右边的0位在x中对应的是1,而该位右边的所有位在x中都是1。通过这种变换,我们可以逆向恢复出最小的x。
