我们知道异或有两个特性:
1. 两个相同的数异或等于0
2. 任何数异或0都等于本身
即:
n ^ n = 0
n ^ 0 = n
利用这个特性可以实现很多的快捷运算和算法题。例如在leetcode中出现的很多问题都可以用异或快速解决。
1. 找出数组中只出现一次的数
数组中,只有一个数出现一次,剩下都出现两次,找出出现一次的数。
这里需要知道一点:
异或运算支持交换律和结合律。
eg.x^y^y^x^z = (x^x)^(y^y)^z = 0^0^z = 0^z = z
所以这里把所有元素进行异或运算,相同的元素都会异或掉变成0,最后剩下的就是只出现一次的元素。
代码:
int find(int[] arr){
int tmp = arr[0];
for(int i = 1;i < arr.length; i++){
tmp = tmp ^ arr[i];
}
return tmp;
}
2. 两数交换
最为常见的两数交换,最常见的写法就是用一个temp变量
int temp = a;
a = b;
b = temp;
那如果不允许用额外的变量呢,还有个更快捷的方法就是用异或运算
x = x^y;
y = x^y;
x = x^y;
看起来很神奇,但其实结合前面说的异或的性质,很容易证明:
第二行代入x的值,y = x^y = (x^y)^y = x^(y^y) = x^0 = x;
所以此时x的值被赋给y了。
第三行带入x和y的值x = x^y = (x^y)^x = (x^x)^y = 0^y = y;
此时,y的值也赋给x了。
还有很多例子,就不一一列举了。在做算法题的时候,可以用异或作为一个新的思路。
网友评论