我们查看源代码的时候总会看一些位运算符号,由于位运算比乘除运算更加高效,所以了解位运算可以帮助我更好地解决一些算法的问题。
- 按位与 & (类似逻辑运算符 &&)
- 按位或 | (类似逻辑运算符||)
- 按位异或 ^ (可以理解为两个数相加,1+1=0,0+1=1,0+0=0)
- 取反 ~ (0变成1,1变成0)
- 左移 << (理解为做乘法,左移多少位就表示乘以2的多少次方)
- 右移 >> (理解为做除法,右移多少位就表示除以2的多少次方)
具体的原理可以看下这篇文章位运算原理
原理知道以后,我们说几个位运算的妙用:
1 奇数和偶数
我们一般的做法是如下:
if(a%2==0) {偶数}
根据位运算的特性
if((a&1)==0) {偶数}
因为偶数一定是末位数为0,而奇数一定是末位数为1,所以和1进行&运算,一定是0或者1
2 交换运算
有一道算法题是这样的:
给定一个非空整数数组,里面有一个元素只出现一次,其他的元素都出现了两次,找出这个只出现一次的元素
拿到这题本能的思路就是map存储键值对,每个元素作为键,出现的次数作为值,最后取出来值为1的元素
如果知道了异或运算,那么这道题可以这么考虑:
1^2^2=1^0=1
如果两个相同的值异或运算就是0,谁和0异或运算都是其本身
所以很容易就是定义一个值让这个值不停的和数组的每个元素做异或运算,最后的值就是那个单独的值