数据结构与算法之位运算

118 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 16 天,点击查看活动详情

作者: 千石
支持:点赞、收藏、评论
欢迎各位在评论区交流

前言

本文内容来自我平时学习的一些积累,如有错误,还请指正

在题目实战部分,我将代码实现和代码解释设置在了解题思路的下方,方便各位作为参考刷题

一些话

本文内容来自我平时学习的一些积累,如有错误,还请指正

前置知识

位运算是通过对二进制数的每一位进行操作来实现的

常见的位运算符包括:按位与(&)、按位或(|)、按位异或(^)、左移位(<<)、右移位(>>)、按位取反(~)等。

下面是位运算的一些基础知识:

  1. 基本原理

位运算是通过对二进制数的每一位进行操作来实现的,对于两个二进制数的位运算,只有对应位置的位相同才会返回1,否则返回0。例如,对于两个二进制数1010和1101进行按位与运算,结果为1000。

  1. 应用场景

位运算可以用于一些特殊的场景,如图形图像处理、网络通信、加密解密等方面。在程序开发中,位运算可以用于优化代码性能,如用位运算代替一些常见的数学运算,可以提高代码效率。

  1. 按位与(&)

按位与运算符(&)的特点是两个二进制数的对应位都为1时,结果的对应位才为1,否则为0。例如,对于两个二进制数1010和1101进行按位与运算,结果为1000。

  1. 按位或(|)

按位或运算符(|)的特点是两个二进制数的对应位只要有一个为1时,结果的对应位就为1,否则为0。例如,对于两个二进制数1010和1101进行按位或运算,结果为1111。

  1. 按位异或(^)

按位异或运算符(^)的特点是两个二进制数的对应位不同时,结果的对应位为1,否则为0。例如,对于两个二进制数1010和1101进行按位异或运算,结果为0111。

  1. 左移位(<<)

左移位运算符(<<)的特点是将一个二进制数的每一位向左移动n位,右侧用0填充。例如,将二进制数1010左移2位,结果为101000。

  1. 右移位(>>)

右移位运算符(>>)的特点是将一个二进制数的每一位向右移动n位,左侧用0填充。例如,将二进制数1010右移2位,结果为0010。

  1. 按位取反(~)

按位取反运算符(~)的特点是将一个二进制数的每一位取反,即0变为1,1变为0。例如,对于二进制数1010进行按位取反运算,结果为0101。

实战

题目一:191. 位1的个数

image.png

思路

可以通过将输入的二进制数转换为字符串,然后遍历字符串来计算其汉明重量。遍历字符串时,每当遇到一个字符为 '1' 时,就将计数器加 1。最后返回计数器的值即可。

代码实现

def hammingWeight(n: int) -> int:
    # 将整数转换为二进制字符串
    binary_str = bin(n)[2:]
    # 计数器初始化为 0
    count = 0
    # 遍历二进制字符串,计算其中 1 的个数
    for char in binary_str:
        if char == '1':
            count += 1
    # 返回计数器的值
    return count

结果展示

image.png

题目二:231. 2 的幂

image.png

思路

如果一个数 n 是 2 的幂次方,那么它的二进制表示中只有一个二进制位是 1,其余位都是 0。如果我们把 n 减去 1,那么二进制表示中原来为 1 的那一位变成了 0,而原来为 0 的那些位都变成了 1。例如,对于数 8(二进制表示为 1000),如果我们将其减去 1,得到 7(二进制表示为 0111)。因此,如果 n 是 2 的幂次方,那么 n & (n - 1) 的结果一定为 0。

代码实现

def isPowerOfTwo(n: int) -> bool:
    if n <= 0:
        return False
    return n & (n - 1) == 0

结果展示

image.png

题目三:

image.png

思路

要颠倒一个给定的 32 位无符号整数的二进制位,可以将其转换为二进制字符串,然后颠倒该字符串,最后将结果转换回整数。

代码实现

def reverse_bits(n: int) -> int:
    # 将整数转换为二进制字符串,左侧补零保证字符串长度为 32
    b_str = bin(n)[2:].zfill(32)
    # 将字符串反转
    b_str_rev = b_str[::-1]
    # 将反转后的字符串转换回整数
    return int(b_str_rev, 2)

结果展示

image.png