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

学习内容

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

二进制&常用知识点梳理

基础位运算

& : 按位与操作,只有两者都为1才是1

性质

归零性:0 & 任何数 = 0

保位性:1 & 任何数= 原数

单调性:执行 x & y之后,得出来得值一定 <=x 且 <= y (只会在原位保留1,而不是凭空产生1)

&简单用法

1、

判断奇偶性 ( x & 1 , 结果1 = 奇数,结果0 = 偶数 , 如果是奇数,那么其二进制位最低位必定为1 )

5 101 & 1 001 = 1 , 6 110 & 1 001 = 0 , 0 0 & 1 1 = 0

使用场景:判断二进制最低位是否为1、比特位计数、交替位判断

2、

检测第k位是否为1 ( x & ( 1 << k ) ), 结果非0则1

1<<k 生成第k位为1其余位为0的数(掩码),与x按位与之后,非0则第k位为1

检测6 110 的第2位是否为1: ( 6 & ( 1 << 2 ) ) != 0

使用场景:子集枚举、位状态判断、逐位遍历二进制数

3、提取数组指定位

构造掩码(目标位置为1,其他位置为0),与x 按位与后,清除无关位,保留目标位

提取最后8位 x & 0xff (每个16进制位 = 4个二进制位,相当于二进制的 1111 1111)

提取最后4位 x & 0x0f

保留奇数位 : x & 0x55555555 ( 32位掩码,奇数位为1 )

使用场景: 字节处理、二进制位拆分、4/8 的幂判定

4、清除数字特定位

构造掩码(目标位置为0,其他位置为1),与x 按位与后 ,目标位置0,保留位不变

x & ~ (1 << k) (清除第k位 , 其中 1 << k 表示目标位为1,其余位为0,~ 为取反)

清除6 110 的第一位, 6 & (~ (1 << 1))

使用场景: 位状态修改、二进制重排、状态压缩

&高阶用法

1、清除数字二进制中 最后一个1 : x & (x - 1)

6 110 & 5 101 = 4 100

5 101 & 4 100 = 4 100

使用场景: 可用来统计1的个数、2的幂判断、比特位计数

2、判定整数是否为2的幂

2的幂的二进制只有1个1, 执行 x & (x-1)之后必为0,且判断数必须排除0和负数

x > 0 && ( x & ( x - 1 ) == 0 )

使用场景:判断2的幂、交替位二进制判断

3、定位负数补码中最后一个1的位置

计算机中的负数以补码形式存储,即 -x = ~x + 1 ,x与-x 按位与会直接保留最后一个1,其余位清0

x & (-x) ,x 为非0整数,正负均适用,直接返回最后一个1的数值

-6 1111 1010 & 6 0000 0110 = 2 0000 0010

5 0000 0101 & -5 1111 1011 = 1 0000 0001

使用场景:快速定位1的位置、树状数组、位分组统计

4、计算二进制加法的进位(配合左移,实现无加减加法)

二进制中同时为1才会产生进位,按位先找到所有的进位位,左移1为表示实际进位值

( a & b ) << 1 (与左移相结合)

3 0011 & 5 0101 = 实际进位位仅为1

使用场景:两整数之和(不用加减乘除做加法)

5、判断全1二进制数 (配合 + 1)

全1的二进制数在加1之后,所有的1全变为0,最高位变为1

x & ( x + 1 ) == 0 (x > 0)

7 0111 & 8 **1000** = 0

使用场景:交替为二进制数

6、4/8的幂判定

4的幂判定:是2的幂基础上,唯一的1在指定奇数位 x > 0 && (x & ( x - 1 ) == 0 ) && (x & 0x55555555 ) != 0

8的幂判定:是2的幂基础上,唯一的1在指定位 x > 0 && (x & ( x - 1 ) == 0 ) && (x & 0x 33333333) != 0

使用场景:判断是否4/8的幂

7、二进制状态压缩的状态判断(重点! 替代数组/哈希表)

用整数的每一个位表示一个状态(是否选中,是否出现)

判断字符串中是否有重复字符: mask & ( 1 << ( c - 'a' ) ) != 0,其他mask是记录状态整数

判断子集是否选中第k个元素:mask & (1 << k ) != 0 (mask为状态压缩数)

空间复杂度从O(n)降到O(1)

使用场景:找不同、找重复数字或字符、选中子集、最大单词长度乘积

& 避坑操作

1、优先级问题

&的优先级低于算术运算、逻辑运算,如果混合运算必须加括号

2、负数处理

负数以补码形式存储,&对负数直接按补码运算,遍历负数时需强转无符号或用无符号右移,避免死循环

3、溢出问题

配合左移<<时,需要用long long / long 来接收结果,或强转无符号,避免溢出

4、边界判断

2/4幂判定中,必须加x > 0 ,否则和负数会误判

相关推荐
lqqjuly3 小时前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1233 小时前
SolidWorks草图转三维DWG技巧
算法
凡人叶枫3 小时前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发
不想写代码的星星3 小时前
std::move 根本不移动,就像老婆饼里没有老婆
c++
redaijufeng4 小时前
C++雾中风景7:闭包
c++·算法·风景
小欣加油4 小时前
leetcode287寻找重复数
数据结构·c++·算法·leetcode
思麟呀4 小时前
C++11 核心特性(三):强类型枚举、static_assert 与 std::tuple
开发语言·c++
一拳一个呆瓜4 小时前
【STL】C++程序的启动与终止
c++·stl
尽兴-5 小时前
2.1 向量基础:Embedding、余弦相似度、欧氏距离、向量检索
算法·embedding·欧氏距离·向量检索·余弦相似度