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

学习内容

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

二进制 | 常用知识点梳理

基础位运算

| : 按位或操作,两者有一个为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,可执行重复赋值操作

相关推荐
繁星蓝雨30 分钟前
C++设计原理———多重继承(虚基类、菱形继承、委托、重命名、基类和成员初始化)
c++·委托·多重继承·mi·显式初始化列·虚基类·对象布局
旖旎夜光1 小时前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
扶尔魔ocy2 小时前
【QT入门到晋级】用开源的自定义控件开发
c++·qt·自定义控件
AiNightVision2 小时前
无人机夜视模块如何选择?——从参数指标到系统集成的完整选型指南
人工智能·算法·计算机视觉·车载系统·无人机·视频·智能硬件
牧羊人.3333 小时前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
akinggw3 小时前
libsherpacore - 基于 sherpa-onnx 的 C++ 语音交互静态库
c++·交互·语音识别
xiaoye-duck3 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
小郎君6584 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
axe_hu4 小时前
AI产品经理的职业规划与学习路径
人工智能·职场和发展·产品经理·学习方法
JJJennie7774 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai