1.遍历二进制位 + 记录奇偶位
题目:奇偶位数
- 遍历一个数的二进制位,记录奇偶位1的个数:
class Solution {
public:
vector<int> evenOddBit(int n) {
vector<int>ans(2);
for (int i = 0; n; i ^= 1, n >>= 1)
ans[i] += n & 1;
return ans;
}
};
- 或者是位掩码,用16进制的0x55555,即二进制的010101...,直接与运算记录对应位置1的个数:
class Solution {
public:
vector<int> evenOddBit(int n) {
const int MASK = 0x5555;
return {__builtin_popcount(n & MASK), __builtin_popcount(n & (MASK >> 1))};
}
};
2.对每一个二进制位取反
题目:数字的补数
简化题目:对一个数num的每一个二进制位取反,去掉前导0后输出对应的十进制数
思路:先求出num最高位的1,假如位置在s,然后设置一个最高位s为1,其余位为0的数字n,即n = 1 << s,然后 n - 1 就是前 s - 1 位都为1的数字,将其与num取反后的数按位与后,就可以实现对num每一个二进制位取反的效果(num的s位取反后肯定为0,所以不用管它)。
忘记取反运算符~
的话看这里 取反运算符
class Solution {
public:
int findComplement(int num) {
int s = -1;
for (int i = 31; i >= 0; --i) {
if ((num >> i) & 1 != 0) {
s = i;
break;
}
}
int n = 1 << s;
return ~num & (n - 1);
}
};
简单一点的取反可以看 4
3.计算二进制位1的个数
题目:位1的个数
一个比较重要的模版,需要记下来
class Solution {
public:
int hammingWeight(int n) {
int ans = 0;
while (n) {
ans++;
n &= (n - 1);
}
return ans;
}
};
4.判断一个数的二进制位是否有相邻的0
求一个数num的二进制位中是否有相邻的0,可以对num取反后求是否有相邻的1。
假如num二进制位有n位,先求一个n位全为1的掩码:mask = (1 << n) - 1 ,num取反后的数x为 x = num ^ mask ,如果 (x & (x >> 1))的结果为0,则表示x的二进制位中没有相邻的1,即num中没有相邻的0。
可以做这道题了:生成不含相邻0的二进制字符串
标签:运算,int,取反,二进制位,num,ans,public From: https://www.cnblogs.com/Amroning/p/18508142