跳转至

位运算

位运算是一种直接对二进制位进行操作的运算方式,效率高,常用于算法优化。

基础位运算符

运算符 名称 说明 示例
& 按位与 两位都为1时结果为1 5 & 3 = 1 (101 & 011 = 001)
| 按位或 有一位为1时结果为1 5 | 3 = 7 (101
^ 按位异或 两位不同时结果为1 5 ^ 3 = 6 (101 ^ 011 = 110)
~ 按位取反 0变1,1变0 ~5 = -6
<< 左移 二进制左移n位,相当于乘以2^n 5 << 1 = 10
>> 右移 二进制右移n位,相当于除以2^n 5 >> 1 = 2

常用技巧

1. 判断奇偶性

# 判断n是否为奇数
if n & 1:
    print("奇数")
else:
    print("偶数")

2. 交换两个数(不用临时变量)

a = a ^ b
b = a ^ b
a = a ^ b

3. 判断第k位是否为1

# 判断n的第k位(从0开始)是否为1
if n & (1 << k):
    print("第k位是1")

4. 将第k位设为1

n = n | (1 << k)

5. 将第k位设为0

n = n & ~(1 << k)

6. 将第k位取反

n = n ^ (1 << k)

7. 取出最低位的1

lowbit = n & (-n)

8. 去掉最低位的1

n = n & (n - 1)

9. 判断是否为2的幂次

# 2的幂次只有一个1
if n > 0 and (n & (n - 1)) == 0:
    print("是2的幂次")

10. 计算二进制中1的个数

def count_ones(n):
    count = 0
    while n:
        n = n & (n - 1)
        count += 1
    return count

经典题目

LeetCode 136. 只出现一次的数字

题目:数组中除了一个数字出现一次外,其余都出现两次,找出只出现一次的数字。

解法:利用异或的性质:a ^ a = 0, a ^ 0 = a

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        result = 0
        for num in nums:
            result ^= num
        return result

LeetCode 191. 位1的个数

class Solution:
    def hammingWeight(self, n: int) -> int:
        count = 0
        while n:
            n &= n - 1
            count += 1
        return count

LeetCode 231. 2的幂

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n > 0 and (n & (n - 1)) == 0

LeetCode 338. 比特位计数

class Solution:
    def countBits(self, n: int) -> List[int]:
        # dp[i] = dp[i & (i-1)] + 1
        result = [0] * (n + 1)
        for i in range(1, n + 1):
            result[i] = result[i & (i - 1)] + 1
        return result

应用场景

  • 状态压缩:用一个整数表示多个布尔状态
  • 集合运算:用位运算实现集合的交、并、补
  • 权限管理:用位表示不同权限
  • 性能优化:位运算速度快,可替代乘除运算