力扣解决二进制 | 题型常用知识点梳理

学习内容

希望各位伙伴在刷力扣的二进制专题时,当然也是我自己的查找字典。后期在做题过程中会不定时补充,不需要左右查找,希望这个可以成为一个二进制字典~

二进制 | 常用知识点梳理

基础位运算

| : 按位或操作,两者有一个为1结果就是1

性质

置1性:1 | 任意二进制位 都为1 (可将目标位强制设定为1 )

保位性: 0 | 任何二进制位 = 原位 (不会清除原有的1,仅对0位生效)

非递减性: 执行 x | y 后,结果数值 >=x 且 >= y (只会增1或保位,不会减位)

&简单用法

1、将数字的第k位强置为1(从最低位0开始,位索引从0开始计数),1 << k 生成 指定位为1,其余位为0的掩码,与 x 进行按位或后,第k位会强制置为1,其他位保持不变

1 << 0 = 1 01

1 << 1 = 2 10

将4的第0位设定位1

4 0100]** \| (1 \<\< 0 ) = 5 **\[0101

使用场景:位状态修改、二进制补位、状态压缩标记

2、提取数字的有效二进制位(补全低位0位1,保留高位1),

通过连续或运算,将数字二进制中最高位1以下的所有0位 置1,快速得到全1的地位掩码

x = 4 100

x |= x >> 1; // x = 4 | 2 = 6 110

x |= x >> 2; // x = 6 | 1 = 7 111

使用场景:生成自定义掩码、二进制位补全、全1数构造

3、合并两个数组的二进制1的位置,两个数的二进制位中,任意一个数的某一位位1,那么结果对应该位即为1

3 011 | 5 101 = 7 111

4 100 | 6 110 = 6 110

使用场景: 多状态合并、二进制特征整合、位信息汇总

4、快速将负数转为全位1掩码,计算机中的负数按照补码存储,负数最高位均位1 , 通过 x | 0 可快速保留补码特性,或通过 ~0|x 直接得到全1数

-1补码为32位全1 (补码:反码+1)

~0相当于-1( ~0对全0取反,结果为全1,对应十进制-1)

~0 | 5 = ~0 -1 | 4 = -1 (意义是验证或运算和全1特性

使用场景: 掩码生成、负数位运算辅助处理

cpp 复制代码
//统计-5的二进制中1的个数
int n = (-5);
int mask = -1; //或~0
unsigned int un = n & mask; //负数转为无符号数
int count = 0;
while(un) { count ++; un &= un -1;  //清除最后一个1}
return count;
&高阶用法

1、二进制状态压缩

用整数的每一位表示一个独立状态(如元素是否选中、字符是否出现、节点是否访问),通过|将目标位设置为1 , 完成状态标记。 int的32位可记录32个状态,long long的64位可记录64个

cpp 复制代码
mask |= (1 << k) (将mask的第k位置1)
int mask = 0;
for(auto c : str) mask |= 1 << ( c - 'a' );  

使用场景: 子集枚举、字符去重、状态压缩DP、路径标记

2、颠倒二进制位/位重排

在颠倒二进制位时,先通过左移为结果留位,在通过|将原数的指定位赋值到结果的目标位,逐位构建最终结果

res = ( res << 1 ) | ( n & 1 ) (每次取n的最低位赋值给res的最低为,res左移留位)

使用场景:自定义位重排、颠倒二进制位

3、配合掩码实现精准位替换

先构造掩码(目标位0、待替换位1),将原数与掩码或运算,把待替换位置1,再结合与运算完成精准替换

x = x | 掩码 ; x = x & ~替换掩码

8 **1000**低3位替换成5 0101 掩码使用7 0111 , 8 | 7 = 15 1111 ,再 15 & ~2 = 13 1101

使用场景:二进制位定制化修改、位重组、掩码组合操作

4、无符号数的高位补0辅助处理

对于有符号数,右值会补符号位,先通过 | 0保证位的原始状态,再结合或运算保留移位后的有效位,避免符号位导致的错误

n = n >>> 1 | 0 (无符号右移后保位)

使用场景:负数二进制位遍历、无符号位运算模拟

5、快速构造连续全1的二进制掩码

构造低m位全1掩码

cpp 复制代码
int mask = (1<< m) -1;  //基础方法
int mask = 0;
if ( m > 0) mask = (mask | (1 << (m-1))) -1 | (1 << ( m -1) );  //兼容m=0

使用场景:自定义位操作、精准位提取清除、动态掩码生成

| 避坑操作

1、优先级问题

| 的优先级低于算术运算、逻辑运算,如果混合运算必须加括号,且算术运算 > 移位运算 > & > ^ > | > 逻辑运算 > 赋值原酸

2、不可逆性:| 操作不可逆,无法反推原始x 与 y

3、数值放大风险: 因 | 操作会新增1的位,运算后数值可能大幅度增大,需要处理溢出用long long / long 来接收结果,或强转无符号,避免溢出

4、负数处理

负数以补码形式存储,高位全为1,与负数执行或运算后,结果必为负数

5、状态压缩位限制

用 mask |= (1 << k)标记状态时,k不能超过变量的位数( int 最大k = 30 ,long long 最大为62 , 避免移位溢出)

6、冗余置1无影响:对于已为1的位重复执行置1操作,结果不变,无需额外判断是否为1,可执行重复赋值操作

相关推荐
♡すぎ♡4 分钟前
镜面 IBL 预过滤贴图的计算
算法·计算机图形学·贴图·pbr
妙为4 分钟前
unreal engine5.7.4,创建ThirdPerson第三人称模版,类型是c++崩溃
c++·ue5·虚幻·unreal engine5
郝学胜_神的一滴8 分钟前
Qt 高级开发 021:零基础吃透 QVBoxLayout 垂直布局
c++·qt
Lsk_Smion23 分钟前
力扣实训 _ [200].岛屿数量
算法·leetcode·深度优先
Boom_Shu30 分钟前
长方形的关系
数据结构·c++·算法
ZhengEnCi1 小时前
O07-银行家算法
算法
装不满的克莱因瓶1 小时前
图像尺寸调整:缩放矩阵如何改变像素坐标?
人工智能·线性代数·数学·算法·机器学习·矩阵
思麟呀1 小时前
C++11并发编程:call_once一次性执行+atomic原子类型+CAS无锁编程+自旋锁
linux·开发语言·jvm·c++·windows
Lumbrologist2 小时前
【C++】零基础入门 · 第 13 节:类与对象基础
java·c++·算法
LONGZETECH2 小时前
软硬协同+故障注入:无人机仿真维修与操控仿真底层算法逻辑拆解
大数据·c语言·算法·3d·unity·无人机