1. 问题背景与核心挑战
今天我们来拆解LeetCode第3314题"构造最小位运算数组I"。这是一道考察位运算特性的中等难度题目,题目要求我们为给定的每个数字num,找到一个满足特定位运算条件的最小整数x。具体来说,我们需要找到满足x | (x + 1) = num的最小x值。
这道题看似简单,但其中蕴含着几个关键挑战:
- 位运算的特性理解:需要深入理解或运算(|)和加法运算在位层面的交互作用
- 暴力解法的优化:如何在看似简单的暴力解法中寻找优化空间
- 边界条件的处理:特别是当num为特定值时的特殊情况处理
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 位运算原理深度解析
2.1 核心等式分析
题目给出的核心等式是x | (x + 1) = num。要理解这个等式,我们需要从二进制层面分析:
当我们在x上加1时,二进制表示中最右边的连续1会被翻转。例如:
- x = 0111 (7)
- x+1 = 1000 (8)
- x | (x+1) = 1111 (15)
这个操作实际上是把x中最低位的0及其右侧的所有1都置为1。因此,我们可以得出一个重要结论:num的二进制表示中必须至少有一个0位,否则无法找到满足条件的x。
2.2 数值模式识别
通过观察不同num值对应的解,我们可以发现一些规律:
- 当num的二进制形式全为1时(如15=1111),没有对应的x满足条件
- 当num是2的幂次方减1时(如7=111),x=num-1
- 当num的最低有效位是0时(如10=1010),x通常等于num-1
这些模式为我们后续的解法优化提供了重要线索。
3. 暴力解法实现与优化
3.1 基础暴力解法
最直观的解法是对每个num,从0开始逐个尝试可能的x值,直到找到满足条件的x或遍历完所有可能。这种方法虽然简单,但效率低下,时间复杂度为O(N×M)。
java复制public int[] minBitwiseArray(List<Integer> nums) {
int[] ans = new int[nums.size()];
for (int i = 0; i < nums.size(); i++) {
int num = nums.get(i);
int x =
