陣列中只出現一次的數字

2021-07-14 08:43:41 字數 1493 閱讀 9680

題目:乙個整形陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。要求時間複雜度是o(n),空間複雜度是o(1)。

例如輸入陣列,因為只有4/6這兩個數字只出現一次,其他數字都出現了兩次,所以輸出4和6。

這是乙個比較難的問題,很少有人能在面試的時候不需要提示一下子想到最好的解決辦法。一般當應聘者想了幾分鐘還沒有思路,面試官會給出一些提示。面試官很可能會說:你可以先考慮這個陣列中只有乙個數字只出現一次,其他的都出現了兩次,怎麼找出這個數字?

這兩個題目都強調乙個(或兩個)數字只出現一次,其他的出現兩次。這有什麼意義呢?我們想到異或運算的乙個性質:

任何乙個數字異或它自己都等於0,。也就是說,如果我們從頭到尾依次異或陣列中的每乙個數字,那麼最終的結果剛好是那個只出現一次的數字,因為那些成對出現兩次的數字全部在異或中抵消了。

想明白怎麼解決這個簡單問題之後,我們再回到原始的問題,看看能不能運用相同的思路。我們試著把原陣列分成兩個子陣列,使得每個子陣列包含乙個只出現一次的數字,而其他數字都成對出現兩次。如果能夠這樣拆分成兩個陣列,我們就可以按照前面的辦法分別找出兩個只出現一次的數字了。

我們還是從頭到尾依次異或陣列中的每乙個數字,那麼最終得到的結果就是 只出現一次的數字的異或結果。因為其他數字都出現了兩次,在異或中全部抵消了。由於這兩個數字肯定不一樣,那麼異或的結果肯定不為0,也就是說在這個結果數字的二進位制表示中至少就有一位為1。我們在結果數字中找到第乙個為1 的位的位置,記為第n位。現在我們以第n位是不是1為標準把原陣列中的數字分為兩個子陣列,第乙個子陣列中每個數字的第n位都是1,而第二個子陣列中每個數字的第n位都是0.由於我們分組的標準是數字鐘的某一位是1還是0,那麼出現了兩次的數字肯定被分配同乙個子陣列。

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

if (data == null || length < 2)

int resultexclusiveor = 0;

for (int i = 0; i < length;i++)

unsigned int indexof1 = findfirstbitis1(resultexclusiveor);

*num1 = *num2 = 0;

for (int j = 0; j < length;j++)

}unsigned int findfirstbitis1(int num)

return indexbit;

}bool isbit1(int num,unsigned int indexbit)

陣列中只出現一次的數字

何海濤 劍指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...