【LeetCode技巧总结】位运算操作技巧

作者:張張張張
github地址:https://github.com/zhanghekai
【转载请注明出处,谢谢!】


★★★由于位运算直接对内存数据进行操作,不需要转成十进制,直接在二进制上进行运算,因此处理速度非常快!!!

一、按位“与”运算符

  • 按位“与”(Bitwise AND),运算符号为:& \&&
  • a & b a\&ba&b 的操作结果:a 、 b a、bab中对应位同时为1,则对应结果位也为1,其余情况对应结果位为0。
    例:
    10010001101000101011001111000 &     111111100000000 − − − − − − − − − − − − − − − − 101011000000000 10010001101000101011001111000\\ \&\qquad\qquad\qquad\;\,111111100000000\\----------------\\\qquad\qquad\qquad\quad10101100000000010010001101000101011001111000&111111100000000101011000000000

1. 用于整数的奇偶性判断

\qquad一个整数a aaa & 1 a\&1a&1这个表达式可以用来判断a aa的奇偶性。二进制的末尾位为0 00表示偶数,末尾位为1 11表示奇数。使用a % 2 a\%2a%2来判断奇偶性和a & 1 a\&1a&1是一样的作用,但是a & 1 a\&1a&1要快好多。

例:当a aa为偶数时,a & 1 a\&1a&1的结果为0 00a = 6 a=6a=6
110 &     1 − − − − − − − − − − − − − − − −   0 110\\ \&\;\,1\\----------------\\\quad\,0110&10

例:当a aa为奇数时,a & 1 a\&1a&1的结果为1 11a = 7 a=7a=7
111 &     1 − − − − − − − − − − − − − − − −   1 111\\ \&\;\,1\\----------------\\\quad\,1111&11

2. 判断a是否是2的正整数幂

\qquad如果一个数a aa他是2 22的正整数幂,那么a aa的二进制形式必定为100000.... 100000....100000....(最高位为1,之后有0个或多个0,注意:2 0 = 1 2^0 =120=11 112 220 00次幂);而a − 1 a-1a1的二进制形式必定是111111... 111111...111111...(全为1 11,但当a = 1 a=1a=1时, a − 1 = 0 a-1=0a1=0)。若a aa2 22的正整数幂,则必有a & ( a − 1 ) a\&(a-1)a&(a1)结果为0 00

例:当a = 16 a=16a=16时:
10000 &   1111 − − − − − − − − − − − − − − − −    0 10000\\ \&\,1111\\----------------\\\quad\quad\;010000&11110

3. 统计二进制数a中1的个数

朴素的统计方法是: 先判断n nn的奇偶性,为奇数时计数器增加1 11,然后将a aa右移一位,重复上面的步骤,知道移位完毕。

公式法: a & ( a − 1 ) a\&(a-1)a&(a1) 的作用是消掉二进制数a aa中最低位的1 11。将a & ( a − 1 ) a\&(a-1)a&(a1) 的结果重新赋值给a aa,继续进行此操作,直到赋值结果为0 00时终止,重复的次数即为a aa1 11的个数。

  • 以python代码为例:7 77的二进制为111 111111
def a1(n):
    count = 0
    while n!=0:
        n = n&(n-1)
        count+=1
    return count

a1(7)

二、按位“异或”运算符

  • 按位“异或”,运算符号为:⋀ \bigwedge
  • a ⋀ b a \bigwedge bab 的操作结果:a 、 b a、bab中对应位相异时(即:一个为0,一个为1),则对应结果位为1,其余情况对应结果位为0。
    例:
    1001 ⋀ 0101 − − − − − − − − − − − − − − − − 1100 \quad 1001\\ \bigwedge0101\\----------------\\\quad1100100101011100
    知识点:
    1. 任何数和0异或为任何数:0 ^ n => n
    2. 相同的数异或为0:n ^ n => 0
    3. 满足交换律a ^ b ^ c <=> a ^ c ^ b

1. 不使用临时变量,交换a和b的值

\qquad只需下列三行代码即可实现:

a = 7
b = 5

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

\qquad最终输出结果为:a = 5 , b = 7 a= 5,b=7a=5,b=7

2. 除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

注意: 相同的数异或为0:n ^ n => 0,且,满足交换律a ^ b ^ c <=> a ^ c ^ b

\qquad只要让数组中的元素依次相“异或”,出现两次的元素最终异或为0,仅剩下唯一只出现过一次的元素。

python代码:

nums=[1,2,3,5,6,4,2,6,3,1,4]

def YiHuo(nums):
    result = 0
    for i in range(len(nums)):
        result = result ^ nums[i]   
    return result

print(YiHuo(nums))

\qquad输出结果为:5 55






【未完,随时更新】


【参考文献】

版权声明:本文为qq_41995574原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。