找出2n 1個數中不成對的那個 公升級版

2021-09-06 08:51:12 字數 1728 閱讀 6248

上篇談到了用異或來解決,確實是個好方法,時間複雜度為o(n),比例一遍ok,空間複雜度為o(1),只占用乙個空間足矣。現在把這個問題公升級下:

(1)給出n個數,其中有且僅有乙個出現了奇數次,其餘的都出現了偶數次。用線性時間常數空間找出這個出現奇數次的數

(2)給定n個數,其中有且僅有兩個出現了奇數次,其餘的都出現了偶數次。用線性時間常數空間找出這兩個出現奇數次的數

原理(原理不是很懂的,先看看上篇

思路

(1)乙個出現奇數次

出現偶數次的一異或為0了,對剩下的奇數次數不造成干擾

奇數次(2n+1)的前2n次一異或為0了,對剩下那個數不造成干擾

剩下的那個數就是結果

(2)兩個出現奇數次

常規的從頭到尾異或一遍,得到數肯定不為0,這個數是那兩個出現奇數次的數異或的結果

找出這個數中不為1的那個位pos(在這個位置處,兩個奇數次的數肯定不同——要是相同這個位也是0)

整個序列根據位pos的值分成兩組(0的一組,1的一組,這樣把出現偶數次的分到一組,無礙。出現奇數次的分到兩組,正好)

對著兩組,利用(1)的方法,解決

細節:如何找到乙個二進位制中第乙個是"1"的位

參考**

int judge(int val, int j)

#include int

main()

, i, j;

int pos = val[0

];

int left=0, right=0; //

分別表示兩個奇數次數

for (i = 1; i < 6; i++)

for (j = 2; ; j *= 2

)

for (i = 0; i < 6; i++) //根據標誌位,分別找出那個奇數次數

printf(

"%d........%d\n

", left, right);

return0;

}

另一寫法(記錄移動次數)

#include using

namespace

std;

void printonenum(int *a, int

size)

cout

<< "

movestep:

"<< movestep <

int left = 0, right = 0

;

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

cout

<< right << "

"<< left <

}int

main()

;

int size = sizeof(a) / sizeof(*a);

printonenum(a, size);

}

找出2n 1個數中不成對的那個

問題定義 有2n 1個數,只有乙個單著,別的都是成對的,找出這個單著的數。比如 2 1 3 2 1。3是答案。思路一 暴力搜尋 每個數都和其他數比較,找不到相同的,就得到了結果。時間複雜度為o n2 思路二 排序搜尋 先給序列排個序,之後從前往後一對一對的找,直到不是成對的為止。時間複雜度,怎麼也得...

找出2n 1個數中不成對的那個

用o n 複雜度搞定。異或操作 對於位操作 相同為0,相異為1.比如 1 0 1,1 1 0 這樣 對於2,1,3,2,1,2 2 1 1 3 3.如此就能將不成對的3找出來。異或具有交換律,所以可以按順序計算,2 1 3 2 1 3。如下 include include include int a...

找出2N 1個兩兩配對數中落單那個

對於這個問題,最暴力的求解方法是採用遍歷的操作,然後全部進行,以下方法使用了乙個輔助類,其原理是乙個智慧型容器,當插入元素的時候判斷集合中是否已經有了該元素,沒有就新增,有的話就刪除,如下 usr bin python def findsingle ls con container for i in...