✏️ 关于专栏:专栏用于记录 LeetCode 中做题与总结
😭 补救 😭
常用位操作
位操作
众所周知,计算机内存都是以二进制的方式在内存中进行储存,而位运算,位运算就是直接对整数在内存中的二进制位进行操作。
▐ 按位与
按位与(&):比较每个位,只有两个位都是 1 时结果为 1。
▐ 按位或
按位或(|):比较每个位,至少有一个位为 1 时结果为 1。
▐ 按位异或
按位异或(^):比较每个位,相同为 0,不同为 1。
▐ 按位取反
按位取反(~):将每一位取反,0 变 1,1 变 0。
▐ 左移
左移(<<):将二进制数向左移动指定的位数,左边空出的位置补零。
左移操作使用符号 < < << <<,将操作数的二进制位向左移动指定的位数。左移操作会将低位补0。
result = operand << n;
operand 是要进行左移操作的整数。
n 是要左移的位数。
result 是左移后的结果。
左移的效果
每向左移一位,相当于乘以2。
注意:左移操作会影响符号位,这可能导致符号变化,需要谨慎使用左移操作,特别是在处理有符号整数时。
▐ 右移
右移(>>):将二进制数向右移动指定的位数,分为算术右移和逻辑右移,C++ 通常实现算术右移(保留符号位)。
右移操作使用符号 >>
,将操作数的二进制位向右移动指定的位数。右移操作的具体行为取决于操作数的类型(无符号或有符号)和编译器的实现。
result = operand >> n;
operand 是要进行右移操作的整数。
n 是要右移的位数。
result 是右移后的结果。
正整数或者无符号数右移效果:
对于正整数或者无符号整数,右移操作会将高位补0。每向又移一位,相当于除以2并向下取整。
负数或者有符号数右移效果:
对于有符号整数,右移操作(>>)可能是算术右移或逻辑右移,这取决于编译器和具体实现。多数现代编译器对有符号整数进行算术右移,即高位用符号位填充。这意味着如果数是正的,补0;如果数是负的,补1。
leetcode例题
▐ 面试题05.01.插入
题目链接:面试题 05.01. 插入
题目描述
给定两个整型数字 N
与 M
,以及表示比特位置的 i
与 j
(i <= j
,且从 0 位开始计算)。
编写一种方法,使 M
对应的二进制数字插入 N
对应的二进制数字的第 i ~ j
位区域,不足之处用 0
补齐。具体插入过程如图所示。
题目保证从 i
位到 j
位足以容纳 M
, 例如: M = 10011
,则 i~j
区域至少可容纳 5 位。
题目示例
示例1:
输入:N = 1024(10000000000), M = 19(10011), i = 2, j = 6
输出:N = 1100(10001001100)
示例2:
输入: N = 0, M = 31(11111), i = 0, j = 4
输出:N = 31(11111)
思路&代码
根据我们已知的位操作,我们先将N的二进制位置i至位置j上面的数置零,然后M左移i位,将N与M相加,即得到插入结果。
class Solution {
public:
int insertBits(int N, int M, int i, int j) {
for(int k = i;k <= j;k++){
if(N&(1<<k)){//判断该位是否为1
N ^= (1 << k);//如果是1,通过异或置零
}
}
M <<= i;
return N + M;
}
};