异或运算
异或运算 ^ 是把数字转化成二进制进行运算,即二进制比较相同位相同的为0,不同的为1。也可以理解为无进位相加
a = 10100101
b = 10101010
a ^ b = 00001111
并且异或运算满足交换律结合律
题目1:一个数组中只有一个数出现了奇数次,求这个数
public static void printOddTimesNum1(int[] arr) { int eor = 0; for (int i = 0; i < arr.length; i++) { eor ^= arr[i]; } System.out.println(eor); }
题解:相同的数异或为零,最后只剩下一个奇数次的数
题目2:一个数组中有两个数出现了奇数次,求这两个数
public static void printOddTimesNum2(int[] arr) { int eor = 0; for (int i = 0; i < arr.length; i++) { eor ^= arr[i]; } // eor = a ^ b // eor != 0 // eor必然有一个位置上是1 int rightOne = eor & (~eor + 1); // 提取出最右的1 int onlyOne = 0; // eor' for (int i = 0 ; i < arr.length;i++) { if ((arr[i] & rightOne) != 0) { onlyOne ^= arr[i]; } } System.out.println(onlyOne + " " + (eor ^ onlyOne)); }
题解:eor & (~eor + 1) 是提取出二进制最右侧的1,我们可以把数分为二进制最右侧为1和最右侧不为1的,然后(arr[i] & rightOne) != 0 选择出二进制最右为一的,然后进行异或操作,即可分出其中最右侧为1的一个数,然后再和eor进行异或得出另一个奇数。