位运算专题
位操作(Bit Manipulation)是程序设计中对位模式或二进制数的一元和二元操作。在许多古老的微处理器上,位运算比加减运算略快,通常位运算比乘除法运算要快很多。在现代架构中,情况并非如此:位运算的运算速度通常与加法运算相同(仍然快于乘法运算)。
位操作包括:
¬¬ 取反(NOT)
∩∩ 按位或(OR) |
⊕⊕ 按位异或(XOR)^
∪∪ 按位与(AND)&
移位 << >>
移位是一个二元运算符,用来将一个二进制数中的每一位全部都向一个方向移动指定位,溢出的部分将被舍弃,而空缺的部分填入一定的值。
移位又分为
算术移位
逻辑移位
【LeetCode 268】
常用异或运算,运用异或运算(两个相同数字异或结果为0)的特性
【LeetCode 231】
如何获取最右边的1
x&(-x)
如何去除最右边的1
x&(x-1)
【面试题05.01】
与运算 全1可以保持不变 全0可以置零
或运算 全0可以保持不变 全1可以置一
怎么设置掩码? 让需要的位置1,让其他不变,然后取反,然后与操作
【面试题05.04】
这里要找1相同的
则意味
更大:从右开始找到第一个0,将它右边的1移动到该位置上
更小:从右开始找到第一个0,将它左边的1移动到该位置
比 num 大的数:从右往左,找到第一个 01 位置,然后把 01 转为 10,右侧剩下的 1 移到右侧的低位,右侧剩下的位清0。
比 num 小的数:从右往左,找到第一个 10 位置,然后把 10 转为 01,右侧剩下的 1 移到右侧的高位,右侧剩下的位置0。
【LeetCode 191】
常用移位操作 ((n>>i)&1)用来判断1
常用n&(n-1)除去1
【LeetCode 190】
ret|=((n>>i)&1)<<(31-i);
【LeetCode 389】
异或操作
【LeetCode 461】
首先进行异或,然后找1
【LeetCode 476】
求反,这里使用的是遍历+移位的方法
class Solution {
public:
int findComplement(int num) {
int ret=0;
int count=0;
while(num!=0)
{
ret|=(1-(num%2))<<count;
num=num/2;
count++;
}
return ret;
}
};
【LeetCode 371】
不适用±求两整数之和
则要使用位运算来实现
两数相异或是无进位的加法
两数相与是进位(需要特殊处理,转化成无符号)
然后将两者相加
【LeetCode 693】
交替位二进制数,这里直接对1进行判断即可
巧妙解法:
通过移位操作将其转化为全1
(n ^ (n >> 1))
然后n&(n+1)
判断是否为0
【LeetCode 762】
巧妙之处在于质数的数目有限,可以打表计算
这样只需要统计1的数量即可
【LeetCode 1342】
注意位运算加括号