1. 问题背景与理解
今天我们来拆解一道有趣的位运算题目——LeetCode 3314. 构造最小位运算数组 I。这道题看似简单,但其中蕴含的位运算技巧却非常值得深入探讨。
题目要求我们根据给定的质数数组nums,构造一个对应的数组ans,使得对于每个下标i,满足ans[i] OR (ans[i] + 1) == nums[i]。如果找不到这样的ans[i],则设为-1。此外,我们需要在所有可能的解中选择最小的ans[i]。
注意:这里的OR是按位或运算,不是逻辑或运算。这是很多初学者容易混淆的地方。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 关键条件解析
2.1 理解OR运算特性
首先,我们需要深入理解题目中的核心条件:ans[i] OR (ans[i] + 1) == nums[i]。这个条件看似简单,但实际上包含了几个重要的位运算特性:
- ans[i]和ans[i]+1在二进制表示上通常只有最低几位不同
- OR运算会将两个数的所有置位位合并
- 由于ans[i]和ans[i]+1是连续整数,它们的二进制形式有特定的关系
2.2 二进制模式分析
让我们观察几个例子来理解这个模式:
-
当ans[i]=1时:
- ans[i] = 01 (二进制)
- ans[i]+1 = 10 (二进制)
- OR结果 = 11 (二进制) = 3 (十进制)
-
当ans[i]=4时:
- ans[i] = 100 (二进制)
- ans[i]+1 = 101 (二进制)
- OR结果 = 101 (二进制) = 5 (十进制)
从这些例子可以看出,满足条件的ans[i]通常具有特定的二进制模式:它必须是一个数,使得当它与它的下一个数进行OR运算时,结果正好等于给定的质数。
3. 解题思路与算法设计
3.1 暴力枚举法
由于题目给出的数据范围很小(nums.length ≤ 100,nums[i] ≤ 1000),我们可以采用暴力枚举的方法:
- 对于每个nums[i],从1开始枚举到nums[i]-1
- 检查当前枚举值j是否满足j | (j+1) == nums[i]
- 如果满足,记录最小的j
- 如果遍历完都没有满足条件的j,则设为-1
这种方法的复杂度是O(n*m),其中n是数组长
