当前位置: 首页 > news >正文

位运算技巧总结

一、常见位运算操作

1、基础位运算

&  按位与  有0则0

|   按位或  有1则1

^   按位异或  相同为0 不同为1

2、确定数n的二进制位中第x位是0还是1

目的:是0返回0,是1返回1

(n >> x) & 1

思路:1除了第一位其他位都是0,用&就可以消去其他位,n右移x位后,原来是0 & 1 = 0,1 & 1 = 1,得到结果不变,则答案成立

3、将数n的二进制的第x位改成1

目的:不能改变其他位

n |= (1 << x)

思路:不能改变除x位有两种做法:|= 0,&= 1,分别对应 (1 << x), ~(1 << x)

但是此题还要把x位改成1,x位只能选择 |= 1,综合来看是 |= (1 << x)

4、将数n的二进制的第x位改成0

目的:不能改变其他位

n &= (~(1 << x))

思路与3类似,不再重复

5、位图思想

int 有32位bit位,所以可以用0,1来表示一些特定的情况,32是容量大小,在一些题中可以用位图节省空间达到O(1)空间复杂度。

6、提取数n二进制中最右侧的1(lowbit)

目的:只留下最右边的1,其余都是0

n & (-n)

思路:首先-n二进制表示成三段。设lowbit下标是数n32位中二进制最右侧的1的下标

[lowbit + 1, 31]:-n取反n所有位

lowbit位:-n与n相同是1

[0, lowbit - 1]:-n与n相同是0

所以-n的本质是将n最右侧的1左边区域全部取反(不包括最右侧1)

所以取反必有0,lowbit右侧全是0,用&

7、消去数n的最右侧1

目的:其余位不变

n & (n - 1)

思路:n - 1本质将最右侧1的右边区域取反(包括1)

所以 [0, lowbit]:取反必有0,用&

[lowbit + 1, 31]:同为0或1,用&不影响

8、异或运算律

a ^ 0 = a

a ^ a = 0

(a ^ b) ^ c = a ^ (b ^ c)

二、例题

1、判断字符是否唯一

. - 力扣(LeetCode)

字母26个,用位图32位表示。0代表未出现过,1代表出现过

核心位运算:判断x位是0还是1,把x位由0变成1

2、丢失的数字

. - 力扣(LeetCode)

只能是0 ~ n里面丢失数字,可以利用下标异或

核心位运算:异或运算律

3、两整数之和

了解无进位加减如何达到加减数字目的,直到进位数是0才能停止相加

核心位运算:

无进位加:就是0 + 0 = 0,0 + 1 = 1,1 + 1 = 0,则用 a ^ b

得到进位:就是0 + 0 = 0,0 + 1 = 0,1 + 1 = 1,还要左移1位,则 (a & b) << 1

4、只出现一次的数字(二)

. - 力扣(LeetCode)

核心位运算:求第x位是0还是1,把第x位变成0,把第x位变成1

5、消失的两个数

(1)异或全部得到 ret

此时有两个不同的数会异或,其余数会被两两消去。

(2)找到 ret 的最右边1的 lowbit 位

我们最终的目的是把一组数分成两组,每组只有一个数的个数是1,那么我们一定要找出两个数的不同点,那就是 lowbit 位不同,那就是一个0,一个1。我们把 lowbit 位是0的放一组, lowbit 位是1的放一组,这样就分开了两个只出现一次的数。

(3)再次检测所有数的 lowbit 位是0还是1,相同进行异或

(4)返回两个数

核心位运算:异或运算律, 求第x位是0还是1


http://www.mrgr.cn/news/22324.html

相关文章:

  • 【智能排班系统】缓存组件封装
  • lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示
  • 35天学习小结
  • 掌握Hive函数[3]:从基础到高级应用
  • HCIA--实验十一:单区域OSPF路由实验
  • Leetcode第414周赛第二题:3281. 范围内整数的最大得分
  • 线程相关内容
  • Arrays.sort()方法在Java中的使用:理论与实践
  • exec与system的区别(C语言)
  • JS中给元素添加事件监听器的各种方法详解(包含比较和应用场景)
  • 国内顶尖的做LLM方向的大学实验室
  • B: 小球反弹
  • 利用TCP编程实现FTP功能
  • ThinkPHP5 5-rce远程代码执行漏洞复现
  • Linux seq命令
  • Java 入门指南:JVM(Java虚拟机)—— Java 内存运行时的数据区域
  • vulhub靶场log4j2漏洞复现
  • Transformer预测 | 基于Transformer心率时间序列预测(tensorflow)
  • 多重继承,虚继承
  • Linux网络——Socket编程函数