题目:给定一个整形数组,其中只有一个数出现了奇数中,其它的数都出现了偶数次,求只出现了奇数次的这个数.
进阶:有两个数出现了奇数次,其它数都出现了偶数次,求这两个数.
完整代码:
package chapter_7_bitoperation;
public class Problem_05_EvenTimesOddTimes {
/**
* 算法思想
* 两个相同的数异或得0,一个数与0异或得它本身
* @param arr
*/
public static void printOddTimesNum1(int[] arr) {
int result = 0;
for(int i=0; i<arr.length; i++){
result ^= arr[i];
}
System.out.println(result);
}
/**
*
* 找出两个奇数的算法思想:
* 一趟异或下来,最终的结果即为那两个奇数异或的结果,
* 如果其结果不为0,则说明至少存在这两个数中的某一个数的某一位不全为0
* 那么可以根据这个不同的位,将数组分成两个部分
*
* 再对这两个独立的部分,两天异或,就可以得到这两个奇数了
* @param arr
*/
public static void printOddTimesNum2(int[] arr) {
int orResult = 0;
int oneResult = 0;
for(int i=0; i<arr.length; i++){
orResult ^= arr[i]; // 异或的结果
}
// 得到两个数右起第一个不相同的位
// 一个数和自己的相反数进行位与,得到的是原数中右起第一个为1,其余都为0的数
// 比如: 3-->0011 --> 0001
int oneRight = orResult&(~orResult+1);
for(int i=0; i<arr.length; i++){
if((arr[i]&oneRight) !=0){ // 根据这不同的位,将数组分成两个部分
oneResult ^= arr[i];
}
}
System.out.println(oneResult + "-" + (oneResult^orResult));
}
public static void main(String[] args) {
int[] arr1 = { 1, 1, 22,22, 33, 33, 4 };
printOddTimesNum1(arr1);
int[] arr2 = { 1, 1, 22,22, 33, 33, 10, 3};
printOddTimesNum2(arr2);
}
}