劍指offer面試題40-數組中只出現一次的數字

題目:

一個整形數組裏除了兩個數字意外,其他的數字都出現了兩次.請寫程序找出這兩個只出現一次的數字.

要求時間複雜度是On,空間複雜度爲O1

這個是上一篇 2016阿里巴巴java筆試題 的增強版...


還是使用異或,異或到了最後得到結果是怎麼樣的呢?

其餘的數字都互相異或變成了0,所以最後的結果就是這2個不相同的數字的異或結果.

就假定要找的兩個數字爲數字A和數字B


那麼怎麼分別得到這2個數字呢?

異或:1^1=0,1^0=1

就看最後異或的結果:他是一個二進制數,那麼出現1的地方肯定就是A與B的二進制不相同的地方.

那麼就異或的結果中,第一次出現1的時候就說明此時A與B中較大的那個當前位上爲1,較小的那個爲0.

根據這個,就把所有的數字分爲2組:當前位爲1的,當前位爲0的.

那麼原先的一組數據被分爲了2組,A,B又分別位於不同的組,那隻要分別異或就行了..


例子:

比如說1,1,2,2,3,4,5,5

最後異或的結果就是3^4=1110

根據倒數第4位上是否爲1,將原先的數組分爲2組:

1,1,2,2,3

4,5,5

這樣分別異或,第一組得到3,第二組得到4,完成


代碼:

public int[] find(int[] array) {

		// 異或所有,得到總異或的結果
		int result = array[0];
		for (int i = 1; i < array.length; i++) {
			result ^= array[i];
		}

		// 求出倒數第幾位爲第一個1
		// 這裏count記錄的是倒數第幾-1
		int count = -1;
		while (result != 0) {
			result = result >>> 1;
			count++;
		}

		// 分爲兩種情況來異或
		int target1 = 0;
		int target2 = 0;

		for (int i = 0; i < array.length; i++) {
			if (((array[i] >>> count) & 1) == 1) {
				target1 ^= array[i];
			} else {
				target2 ^= array[i];
			}
		}

		return new int[] { target1, target2 };
	}


發佈了91 篇原創文章 · 獲贊 18 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章