异或位运算在算法中的运用
先来简单了解一下异或这种位运算:
其实只要理解一句话就能很好的掌握异或运算:相同为0,不同为1.例如1^0=1;0^1=1;0^0=0;1^1=0;
一般规律:1、a^a=0;a^0=a;
2、满足结合律和交换律,如:a^b^a=a^a^b;
如何理解上述的规律1?,其实异或位运算可以看成是不进位的加法运算:
如果是a^a:
a^0=a类似。
异或位运算运用在算法中:
-
运用于swap(交换)中
常见的两个变量互相交换值需要额外用到一个空间单位,(以a、b两个变量为例)
int c;c=a;a=b;b=c;
其空间复杂度为O(1)。
利用异或可以将空间复杂度降为0:
a=a^b;b=a^b;a=a^b;
解释:
-
常考的算法题
要求:时间复杂度为O(n),空间复杂度为O(1)
(1)在一组整形数组中,有一种数出现了奇数次,其他数出现了偶数次,请找出这个出现奇数次的数。
这问很简单,直接利用规律即可解决。
最后的eor就是结果;
(2)在一组整形数组中,有两种数出现了奇数次,其他数出现了偶数次,请找出这个这两个出现奇数次的数。
分析:这问相对来说比较难。首先还是采用(1)问的eor,不过此时的eor=a^b;要注意,此时eor不等于0(题中讲了是两种数),那就以为着eor的某一位上肯定是1(整数32bit,即8位),就要利用这个特殊的“1”(至少有一位是1,可能有几个,只要用到1个)。在这一位上,a、b不相等,一个为1,另一个为0,以这一位为条件,将这组整形数组分成两类,一类在这一位上是1,另一类在这一位是0:a、b分别在这两类中。将其中一类中的所有数依次异或,得到的结果是a、b中的一个(eor‘)。最后,eor^eor'的结果就为a、b中的另一个。
如何找到那个1呢?
这里找eor的最右边的1:eor&(~eor+1),例如:
代码:
举例:
以第二位为条件分类。