LeetCode 2275: 按位与结果大于零的最长组合题解
1. 题目分析
这道题目考察了位运算的基本概念和应用。我们需要在给定的数组中找出最长的子序列,使得这些数字进行按位与运算后的结果大于0。
1.1 关键概念
-
按位与运算 (&)
- 两个二进制位都为1时,结果为1。
- 只要有一个为0,结果就为0。
- 多个数字按位与时,某一位只要出现一个0,最终结果该位就是0。
2. 解题思路
2.1 核心思想
要使得按位与的结果大于0,意味着结果中至少有一位是1。反过来思考:
- 如果一组数字按位与结果大于0,那么这组数字必然在某个二进制位上都是1。
2.2 算法步骤
- 遍历每一个二进制位(0-31位)。
- 对于每一位,统计数组中有多少个数字在这一位上是1。
- 所有位置中,出现1最多的那个位置的计数就是我们要的答案。
3. 代码实现
class Solution {
public:
int largestCombination(vector<int>& candidates) {
int result = 0;
// 遍历32位
for (int bit = 0; bit < 32; bit++) {
int count = 0;
// 统计在当前位上为1的数字个数
for (int num : candidates) {
if ((num >> bit) & 1) {
count++;
}
}
result = max(result, count);
}
return result;
}
};
4. 代码详解
4.1 位运算技巧
-
num >> bit
:将num
右移bit
位。- 例如:
12 >> 2 = 3
(1100 -> 0011
)
- 例如:
-
& 1
:与1进行按位与运算。- 用于检查最右边的位是否为1。
- 例如:
3 & 1 = 1
(0011 & 0001 = 0001
)
4.2 时间复杂度分析
- 外层循环:32次(固定次数)
- 内层循环:
n
次(n
为数组长度) - 总时间复杂度:
O(32 * n) = O(n)
4.3 空间复杂度分析
- 只使用了常数个变量
- 空间复杂度:
O(1)
5. 相关知识点扩展
5.1 常见的位运算操作
- 获取第
k
位:(num >> k) & 1
- 设置第
k
位为1:num |= (1 << k)
- 设置第
k
位为0:num &= ~(1 << k)
- 判断是否是2的幂:
(n & (n-1)) == 0
5.2 位运算的应用场景
- 状态压缩
- 权限管理
- 标志位操作
- 优化空间使用
6. 总结
这道题目是位运算的经典应用:
- 利用了按位与运算的特性
- 通过逆向思维简化问题
- 展示了如何高效处理二进制位的统计问题掌握这类问题对于理解计算机底层运算和优化算法都有很大帮助。