LeetCode 刷题必懂位运算

LeetCode 刷题必懂位运算

💡 原文中文,约4200字,阅读约需10分钟。
📝

内容提要

本文介绍LeetCode刷题所需的位运算知识,包括Go语言中的AND、OR、XOR、取反和位移运算,负数补码表示及溢出处理,并通过三个练习演示位运算技巧:判断第n位是否为1、判断是否为2的整数次幂、计算两数需改变多少位,最后介绍Go标准库bits包的常用位操作方法。

🔎

延伸解读

补码与溢出:理解负数位运算的关键

文章用 -1 和 -128 的例子说明,有符号整型在计算机中用补码表示,补码等于原码取反加一。这解释了为什么 ^127 的结果是 -128。同时,溢出时最高位会被省略,例如 -1 加 1 得到 0,-128 加 127 得到 -1。在 LeetCode 中处理负数位运算时,必须考虑补码和溢出行为,否则容易得到错误结果。

三个练习背后的通用位运算模式

判断第 n 位是否为 1 使用 K & (1 << n);判断 2 的整数次幂使用 K & (K-1) == 0;计算两数不同位数使用异或后统计 1 的个数。这些练习展示了位运算的常见模式:构造掩码、利用二进制特征、以及通过异或找差异。掌握这些模式后,可以灵活解决类似问题,而不仅仅是记住具体代码。

Go 标准库 bits 包:提升位运算效率

文章介绍了 bits 包中的常用方法,如 Len 计算二进制长度、OnesCount 统计 1 的个数、Reverse8 反转位、LeadingZeros8 和 TrailingZeros8 计算前导和尾随零。这些方法比手动循环更简洁高效,在 LeetCode 中可以直接使用,但需注意它们针对无符号整数,使用时要注意类型转换和位数限制。

❓

Q&A

Go语言中位运算符 &、|、^ 分别代表什么运算?

& 是按位与,只有两个对应位都为1时结果位才为1;| 是按位或,只要有一个对应位为1结果位就为1;^ 是按位异或,只有两个对应位不相等时结果位才为1。

计算机中负数是如何用二进制表示的?

计算机用补码表示负数。补码的计算方法是:先取负数的绝对值的二进制作为原码,然后将原码按位取反,最后加1。例如 -1 的补码是 11111111。

如何判断一个整数是否为2的整数次幂?

2的整数次幂的二进制表示中只有一位为1,其余位为0。因此可以用 K & (K-1) == 0 来判断,如果结果为0,则K是2的整数次幂,否则不是。

怎样计算两个整数之间需要改变多少位才能互相转换?

先对两个数进行异或运算,得到的结果中1的个数就是需要改变的位数。例如 7 ^ 6 = 1,二进制中只有1位为1,所以需要改变1位。

Go标准库bits包提供了哪些常用的位操作方法?

bits包提供了:bits.Len计算二进制表示长度,bits.OnesCount计算1的个数,bits.Reverse8反转8位二进制,bits.LeadingZeros8和bits.TrailingZeros8分别计算前导零和末尾零的个数。

如何判断一个整数的第n位是否为1?

构造一个只有第n位为1、其他位为0的数(通过 1 << n 得到),然后与整数K进行按位与运算。如果结果大于0,则第n位为1;否则为0。

🏷️

标签

➡️

继续阅读