利用异或实现一些快捷的算法技巧

我们知道异或有两个特性:

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了。

还有很多例子,就不一一列举了。在做算法题的时候,可以用异或作为一个新的思路。

你可能感兴趣的:(利用异或实现一些快捷的算法技巧)