首先介绍一些基本概念
按位与操作(&
)
是一种位运算,它逐位比较两个二进制数,并根据如下规则返回一个新的二进制数:
- 1 & 1 = 1
- 1 & 0 = 0
- 0 & 1 = 0
- 0 & 0 = 0
简单来说,只有当两个对应位都是 1
时,结果才是 1
;否则结果为 0
。
按位与操作的示例
假设有两个整数 5 和 3,它们的二进制表示分别是:
- 5 的二进制:
0101
- 3 的二进制:
0011
异或操作(XOR,^
)
是一种位运算符,它对两个二进制数的每一位进行比较,并根据如下规则生成一个新的二进制数:
- 相同的位:结果为
0
- 不同的位:结果为
1
示例:
假设有两个数 5
和 3
,它们的二进制表示分别是:
5
的二进制表示:0101
3
的二进制表示:0011
- 现在对它们进行异或运算:
-
0101 (5) ^ 0011 (3) ------- 0110 (结果是 6)
补码
比如5的二进制串是:"101",那么~5(补码)就是"010"。全部取反即可
lowbit操作
是一种在二进制数中获取数字的 最低位的1 的值的操作,常用于一些算法和数据结构中,比如树状数组(Fenwick Tree)等。
Lowbit定义:对于一个整数 x
,lowbit(x)
返回它的二进制表示中最右边的 1
及其对应的值(即最低位的 1
的值)。lowbit(x)
的计算方式是:lowbit(x) = x & -x
这个公式利用了二进制的补码性质来找到 x
中的最低位 1
。
为什么 x & -x
可以得到 lowbit?
- 对于一个数
x
,它的 负数(-x
)可以通过取补码表示。负数-x
的补码是x
的反码(即逐位取反)加1
。 x & -x
的结果正好是x
中最低位的1
,其他所有位都是0
。原因是-x
在二进制上会保留x
中从最低位的1
及其后面的所有 0,其他高位则取反。
示例:
以 12
为例:
12
的二进制表示为:1100
-12
的二进制表示为:0100
(将1100
取反并加1
)-
1100 (12) & 0100 (-12) ------- 0100 (结果是 4)
二进制中1的个数(模板题)
给定一个长度为 n 的数列,请你求出数列中每个数的二进制表示中 1 的个数。
输入格式
第一行包含整数 n。
第二行包含 n 个整数,表示整个数列。
输出格式
共一行,包含 n 个整数,其中的第 ii 个数表示数列中的第 ii 个数的二进制表示中 11 的个数。
数据范围
1≤n≤100000,
0≤数列中元素的值≤10^9
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2
代码
#include <iostream>
using namespace std;
int n;
int lowbit(int x){
return -x & x;
}
int main()
{
int n;
cin >> n;
while(n --){
int x;
int res = 0;
cin >> x;
while(x){
res ++;
x -= lowbit(x);
}
cout << res << " ";
}
return 0;
}
构造最小位运算数组|| (lowbit操作的应用)
给你一个长度为 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 <= 100
2 <= nums[i] <= 109
nums[i]
是一个质数。
代码
class Solution {
public:
int lowbit(int x){
return -x & x;
}
vector<int> minBitwiseArray(vector<int>& nums) {
int n = nums.size();
for(int i = 0;i < n;i ++){
int x = nums[i];
if(x == 2){
nums[i] = -1;
continue;
}
nums[i] ^= lowbit(~x) >> 1;
}
return nums;
}
};
加油