内容提要
本文介绍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。