陣列中只出現一次的數字

2022-06-16 18:21:11 字數 1874 閱讀 5394

乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。

數字都出現兩次,則異或肯定為0。

考慮下這個題目的簡化版——陣列中除乙個數字只出現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了。

1

class

solution

14for(i=0;i)

18else

19 *num2^=data[i];20}

21}22 };

擴充套件:陣列a中,除了某乙個數字x之外,其他數字都出現了三次,而x出現了一次。請給出最快的方法找到x。我們換乙個角度來看,如果陣列中沒有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次的數字。

1

//【白話經典演算法系列之十七】陣列中只出現一次的數2//

by morewindows(

3//歡迎關注http:

4 #include 5 #include

6int findnumber(int a, intn)7

22int

main()23;

30 printf("

%d\n

", findnumber(a, maxn));

31return0;

32 }

執行結果如下圖所示:

陣列中只出現一次的數字

何海濤 劍指offer 名企面試官精講典型程式設計題 九度oj 題目描述 乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。輸入 每個測試案例包括兩行 第一行包含乙個整數n,表示陣列大小。2 n 10 6。第二行包含n個整數,表示陣列元素,元素均為int。輸...

陣列中只出現一次的數字

來自劍指offer 分析 如果整型陣列中只有乙個數字出現一次,我們只需將陣列中每個元素依次做異或操作,最終就得到了只出現一次的數字。因為自己與自己異或後,結果為0.現在,陣列中有兩個數字只出現一次,上述一次遍歷後將所有元素異或得不到那兩個數字。因此,我們試著將原陣列分成兩個子陣列,使每個子陣列中分別...

陣列中只出現一次的數字

package com.google.android public static void main string args int result new int 2 find data,result for int i result private static void find int dat...