首先來看題目要求:
在乙個陣列中除兩個數字只出現1次外,其它數字都出現了2次, 要求盡快找出這兩個數字。
考慮下這個題目的簡化版——陣列中除乙個數字只出現1次外,其它數字都成對出現,要求盡快找出這個數字。這個題目在之前的《
位操作基礎篇之位操作全面總結
》中的「位操作趣味應用」中就已經給出解答了。根據異或運算的特點,直接異或一次就可以找出這個數字。
現在陣列中有兩個數字只出現1次,直接異或一次只能得到這兩個數字的異或結果,但光從這個結果肯定無法得到這個兩個數字。因此我們來分析下簡化版中「異或」解法的關鍵點,這個關鍵點也相當明顯——陣列只能有乙個數字出現1次。
設題目中這兩個只出現1次的數字分別為a和b,如果能將a,b分開到二個陣列中,那顯然符合「異或」解法的關鍵點了。因此這個題目的關鍵點就是將a,
b分開到二個陣列中。由於a,b肯定是不相等的,因此在二進位製上必定有一位是不同的。根據這一位是0還是1可以將a,b分開到a組和b組。而這個陣列中其它數字要麼就屬於a組,要麼就屬於b組。再對a組和b組分別執行「異或」解法就可以得到a,b了。而要判斷a,b在哪一位上不相同,只要根據a異或b的結果就可以知道了,這個結果在二進位製上為1的位都說明a,b在這一位上是不相同的。
比如int a =
整個陣列異或的結果為3^5即0x0011 ^ 0x0101 = 0x0110
對0x0110,第1位(由低向高,從0開始)就是1。因此整個陣列根據第1位是0還是1分成兩組。
a[0] =1 0x0001 第一組
a[1] =1 0x0001 第一組
a[2] =3 0x0011 第二組
a[3] =5 0x0101 第一組
a[4] =2 0x0010 第二組
a[5] =2 0x0010 第二組
第一組有,第二組有,明顯對這二組分別執行「異或」解法就可以得到5和3了。
分析至些,相信**不難寫出,下面給出完整的源**:
//陣列中除兩個數字外,其它數字都出現了次。要求盡可能快的找出這兩個數字
//by morewindows (
#include void findtwonotrepeatnumberinarray(int *a, int n, int *pn1, int *pn2)
void printfarray(int a, int n)
int main()
; int a[maxn] = ;
printf("陣列為: \n");
printfarray(a, maxn);
int nnotrepeatnumber1, nnotrepeatnumber2;
findtwonotrepeatnumberinarray(a, maxn, &nnotrepeatnumber1, &nnotrepeatnumber2);
printf("兩個不重複的數字分別為: %d %d\n", nnotrepeatnumber1, nnotrepeatnumber2);
return 0;
} 陣列a
中,除了某乙個數字
x之外,其他數字都出現了三次,而
x出現了一次。請給出最快的方法找到x。
這個題目非常有意思,在本人部落格中有《
位操作基礎篇之位操作全面總結
》這篇文章介紹了使用位操作的異或來解決——陣列中其他數字出現二次,而x出現一次,找出x。有《
》這邊文章介紹了分組異或的方法來解決——陣列中其他數字出現二次,而x和y出現一次,找出x和y。而這個題目則是其他數字出現3次,x出現一次。
應該如何思考了?
前兩篇文章是利用兩個相同的數異或結果為0來計算的,但這個題目中其他數字是出現了3次,因此肯定不可以再使用異或了。
我們換乙個角度來看,如果陣列中沒有x,那麼陣列中所有的數字都出現了3次,在二進位製上,每位上1的個數肯定也能被3整除。如從二進位製上看有:
1:0001
5:0101
1:0001
5:0101
1:0001
5:0101
二進位制第0位上有6個1,第2位上有3個1.第1位和第3位上都是0個1,每一位上的統計結果都可以被3整除。而再對該陣列新增任何乙個數,如果這個數在二進位制的某位上為
1都將導致該位上
1的個數不能被
3整除。因此通過統計二進位製上每位1的個數就可以推斷出x在該位置上是0還是1了,這樣就能計算出x了。
推廣一下,所有其他數字出現n(n>=2)次,而乙個數字出現1次都可以用這種解法來推導出這個出現1次的數字。
示範**如下:
// 【白話經典演算法系列之十七】陣列中只出現一次的數
// by morewindows( )
// 歡迎關注
#include #include int findnumber(int a, int n)
int main()
; printf("%d\n", findnumber(a, maxn));
return 0;
}
陣列中只出現一次的數
首先看看題目要求 陣列 a中,除了某乙個數字 x之外,其他數字都出現了三次,而 x出現了一次。請給出最快的方法找到x。這個題目非常有意思,在本人部落格中有 位操作基礎篇之位操作全面總結 這篇文章介紹了使用位操作的異或來解決 陣列中其他數字出現二次,而x出現一次,找出x。有 這邊文章介紹了分組異或的方...
陣列中只出現一次的數
題目1 乙個陣列中,除了某乙個只出現過一次的數字外,其餘數字均出現過2次,找出這個只出現了一次的數字。思路 分析題幹,發現強調了陣列中數字出現的次數為1和2,則可以想到異或運算,兩個相同的數字異或結果為0,相同的數異或的結果為其本身,且異或運算存在交換律和結合律,即a b a b,b a a b。那...
陣列中只出現一次的數
題目 乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。思路 首先 位運算中異或的性質 兩個相同數字異或 0,乙個數和0異或還是它本身。當只有乙個數出現一次時,我們把陣列中所有的數,依次異或運算,最後剩下的就是落單的數,因為成對兒出現的都抵消了。依照這個思路...