Bit Arithmetic
位运算
- 简介:程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。常见的运算符有与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>是带符号右移 >>>无符号右移动)。
- 优点:可以直接对二进制数进行操作,执行速度比较快,而且可以节省内存空间,特别是在处理大规模数据时,优势更加明显。
- 应用场景:常用于处理二进制数据,如位图压缩、哈希表实现、位集合操作等。也可以用于加密算法、图像处理、网络协议等领域。
- 时间复杂度:通常是$O(1)$,因为它们直接对二进制位进行操作,而不需要循环或递归等复杂的计算过程。
- 技巧:
- 按位与&:
- 判断一个数的奇偶性(
x & 1 == 0
表示x是偶数,x & 1 == 1
表示x是奇数) - 清零一个数的某一位(
x &= ~(1 << n)
表示将x的第n位清零) - 判断一个数是否是2的幂次方。例如:
(x & (x - 1)) == 0
表示x是2的幂次方 - Brian Kernighan算法:消除数字n的二进制表示中的最后一位1,也即计算汉明权重(Hamming Weight):
n & (n-1)
- 取出 x 的二进制表示中最低位的1 :
x & -x
- 判断一个数的奇偶性(
- 按位或|:
- 将一个数的某一位设置为1 (
x |= (1 << n)
表示将x的第n位设置为1)
- 将一个数的某一位设置为1 (
- 按位异或^:
- 可以用来交换两个变量的值(
a ^= b; b ^= a; a ^= b;
) - 检查一个数是否出现了奇数次。对于数组中出现两次的数,使用异或操作可以找到它们,任何数和其自身做异或运算,结果是0,即
a ^ a = 0
- 任何数和 0 做异或运算,结果仍然是原来的数,即
a ^ 0 = a
- 异或运算满足交换律和结合律,即
a ⊕ b ⊕ a = b ⊕ a ⊕ a = b ⊕ (a ⊕ a) = b ⊕ 0 = b
- 可以用来交换两个变量的值(
- 左移位<<:可以用来计算2的幂次方(
1 << n
表示2的n次方) - 右移位>>:可以用来计算除以2的幂次方(
x >> n
表示将x除以2的n次方)
- 按位与&:
- 常用方法:
bin()
获取数字的二进制值ord()
输入单个字符返回其ASCII值(0-255)或unicode值chr()
输入一个整数[0,255]返回其ASCII值int("s",x)
将指定进制x的字符s转换成十进制值- 正数的反码和补码都与原码相同。负数的二进制用补码表示。负数的反码为对该数的原码除符号位外各位取反。负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1 。
Python 没有 int, long 等不同长度变量,即在编程时无变量位数的概念。
- 获取负数的补码:需要将数字与十六进制数 0xffffffff 相与。可s理解为舍去此数字 32 位以上的数字(将 32 位以上都变为 00),从无限长度变为一个 32 位整数。
- 返回前数字还原: 若补码 aaa 为负数( 0x7fffffff 是最大的正数的补码 ),需执行
~(a ^ x)
操作,将补码还原至 Python 的存储格式。 a ^ x 运算将 1 至 32 位按位取反; ~ 运算是将整个数字取反;因此, ~(a ^ x) 是将 32 位以上的位取反,1 至 32 位不变
参考博客:
力扣指南
位运算 | ||
---|---|---|
题目 | 技巧 | 难度 |
✅67. 二进制求和 | 简直不是人想出来的!!! | 🌟 |
✅136. 只出现一次的数字 | a ^ 0 = a; a ^ a = 0 | 🌟 |
✅137. 只出现一次的数字 II | (a >> i) & 1 取出a的第i位 | 🌟🌟 |
✅187. 重复的DNA序列 | 用二进制表示x = ((x << 2) | bin[ch]) & ((1 << 20) - 1) | 🌟🌟 |
❌✅190. 颠倒二进制位 | 还有个分治法 | 🌟 |
✅191. 位1的个数 | n & (n - 1)消除二进制n的最后一位1 | 🌟 |
✅201. 数字范围按位与 | 寻找公共前缀,n&(n-1)消除最后一位1 | 🌟🌟 |
✅231. 2 的幂 | 同191 260 | 🌟 |
✅260. 只出现一次的数字 III | x的最后一位1:x & -x | 🌟🌟 |
✅268. 丢失的数字 | a ^ a = 0 | 🌟 |
❌287. 寻找重复数 | 难以理解 | 🌟🌟 |
✅318. 最大单词长度乘积 | 将字母用掩码表示,取并为0则表示二者没用重复字符 | 🌟🌟 |
❌✅338. 比特位计数 | x&(x-1)消除1,还有动态规划解法 | 🌟 |
✅342. 4的幂 | 4的幂是2的偶数次幂,且%3=1 | 🌟 |
✅371. 两整数之和 | python整型无限长,用32位补码表示32位有符号整型,负数最高位全为1 | 🌟🌟 |
✅389. 找不同 | ord(a), chr(1) | 🌟 |
✅645. 错误的集合 | 同260 | 🌟 |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment