題目描述
一個整型數組裏除了兩個數字之外,其他的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。
思路:
此題考察的是異或運算的特點:即兩個相同的數異或結果爲0。
此題用了兩次異或運算特點:
(1)第一次使用異或運算,得到了兩個只出現一次的數相異或的結果。
(2)因爲兩個只出現一次的數肯定不同,即他們的異或結果一定不爲0,一定有一個位上有1。另外一個此位上沒有1,我們可以根據此位上是否有1,將整個數組重新劃分成兩部分,一部分此位上一定有1,另一部分此位上一定沒有1,然後分別對每部分求異或,因爲劃分後的兩部分有這樣的特點:其他數都出現兩次,只有一個數只出現一次。因此,我們又可以運用異或運算,分別得到兩部分只出現一次的數。
//num1,num2分別爲長度爲1的數組。傳出參數
//將num1[0],num2[0]設置爲返回結果
public static void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length <= 1){
num1[0] = num2[0] = 0;
return;
}
int len = array.length, index = 0, sum = 0;
for(int i = 0; i < len; i++){
sum ^= array[i];
}
for(index = 0; index < 32; index++){
if((sum & (1 << index)) != 0) break;
}
for(int i = 0; i < len; i++){
if((array[i] & (1 << index))!=0){
num2[0] ^= array[i];
}else{
num1[0] ^= array[i];
}
}
}
/**
* 數組a中只有一個數出現一次,其他數都出現了2次,找出這個數字
* @param a
* @return
*/
public static int find1From2(int[] a){
int len = a.length, res = 0;
for(int i = 0; i < len; i++){
res = res ^ a[i];
}
return res;
}