劍指offer 陣列中只出現一次的數字C

2021-10-13 18:58:39 字數 1645 閱讀 4691

兩種方法

1.記錄次數、個數啥的都考慮雜湊表,如果沒有好的辦法就用這個

2.位運算

我們先來看乙個比較簡單的情況,如果陣列中只有乙個數字出現一次,其他都出現兩次。那麼我們應該可以想到異或運算(^),與運算(&)是均為1才是1,其他均為0。異或運算有乙個比較好的性質是:相同為0,相異為1。也就是說,任何乙個數字異或它自己都等於0,而0異或任何數都等於那個數。因此,我們從頭到尾依次異或陣列中的每個數字,那麼最終結果剛好是那個只出現一次的數字,重複的數字在異或過程中被抵消了。

這是一種比較巧妙的思路,然而,本題只出現一次的數字有兩個,簡單的異或無法解決。但是,借助這種思路,我們可以進一步分析,如果我們能把陣列分成兩個子陣列,使每個子陣列包含乙個只出現一次的數字,而其他數字成對出現,那麼我們通過上述解法就可以找到兩個元素。

具體思路是:我們首先仍然從前向後依次異或陣列中的數字,那麼得到的結果是兩個只出現一次的數字的異或結果,其他成對出現的數字被抵消了。由於這兩個數字不同,所以異或結果肯定不為0,也就是這個異或結果一定至少有一位是1,我們在結果中找到第乙個為1的位的位置,記為第n位。接下來,以第n位是不是1為標準,將陣列分為兩個子陣列,第乙個陣列中第n位都是1,第二個陣列中第n位都是0。這樣,便實現了我們的目標。最後,兩個子陣列分別異或則可以找到只出現一次的數字。

以為例:

我們依次對陣列中的每個數字做異或執行之後,得到的結果用二進位制表示是0010。異或得到結果中的倒數第二位是1,於是我們根據數字的倒數第二位是不是1分為兩個子陣列。第乙個子陣列中所有數字的倒數第二位都是1,而第二個子陣列中所有數字的倒數第二位都是0。接下來只要分別兩個子陣列求異或,就能找到第乙個子陣列中只出現一次的數字是6,而第二個子陣列中只出現一次的數字是4。

class

solution

bool flag = false;

for(int i = 0; i < data.size(); ++i)

else if(hashtable[data[i]] == 1 && flag)

}*///將所有數字依次異或,如果只有乙個出現一次的數字,那麼異或後的結果就是這個數字

//但是有兩個數字,而且這兩個數字不同,所以最後的結果不為0

//不為0,證明結果中一定有一位為1,然後這兩個數字的這一位一定是乙個為0,乙個為1

//按照這一位的數字對這個陣列進行分類,對兩個數字分別進行異或

if(data.

size()

==2)int res =0;

for(

int i =

0; i < data.

size()

;++i)

//接下來是找到res中第一位(從後往前第一位)為1的位數

int index =0;

//0011>>2=0000,1100<<1=1000

for(

;index<32;

++index)

for(

int i =

0; i < data.

size()

;++i)

else

}return;}

};

劍指offer 陣列中只出現一次的數字

1 乙個數字出現一次,其他數字出現兩次 兩個相同的數異或為0,所以將陣列裡的所有數依次異或,得到的結果就是只出現一次的數。include using namespace std int main int num 0 for int i 0 i 7 i cout 2 乙個數字出現一次,其他數字出現n次...

劍指offer 陣列中只出現一次的數字

乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。解法 首先考慮如果陣列中只有乙個數字出現一次,其他的數字都出現兩次,怎麼找出這個只出現一次的數字?這裡需要用到異或運算的性質 乙個數字 不管是什麼形式的數字,只要其二進位制形式確定 和其自身的異或運算的結果一...

《劍指offer》 陣列中只出現一次的數字

乙個整型陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。解法 1.了解幾個常識 a.了解兩個相同的數字異或結果為0 b.任何數字與0進行異或結果為數字本身 c.任何數字與1相與,只有最低位 右邊 為1時候,才等於1 2.一種對陣列分成兩組的方法,比如2 10 和3...