问题描述
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
解题思路
如果数组中只有一个数字出现奇数次,则将数组中所有的数字做异或可得该数字。
数组中有两个数字出现奇数次,设这两个数字分别为a、b,则将数组中所有的数字做异或得到的是a与 b异或的结果,设为xor。
数字a与b不同,则a与b的二进制表示中至少存在1位不同,xor二进制表示中为1的位即是a与b不同的位,假设a与b的第k位不同,a在该位上为1,b在该位上为0 。(k可以选取为从起始位开始的第一个不同的位)
则可以根据数字第k位的取值情况将数组分为两个字数组,第k位为1的子数组必包含a与其他出现偶数次的数字(相同的数字第k位肯定相同),第k位为0的子数组必包含b与其他出现偶数次的数字。
子数组中的数字做异或可分别得到数字a与b。
实现代码
//num1,num2分别为长度为1的数组。传出参数 //将num1[0],num2[0]设置为返回结果 public void findNumsAppearOnce(int[] array, int num1[], int num2[]) { // 得到两个数字的异或结果xor int xor = 0; for (int i=0; i<array.length; i++) xor ^= array[i]; // 求两个数字第一个不同的位, 有temp记录 // 若temp=00100000 表示两个数字的第6位不同 int temp = 1; while ((xor & 1) != 1) { temp = temp << 1; xor = xor >> 1; } // 根据temp将数组分为两个子数组,并分别做异或 num1[0] = 0; num2[0] = 0; for (int i=0; i<array.length; i++) if ((array[i]&temp) == temp) num1[0] ^= array[i]; else num2[0] ^= array[i]; }