題目:
讀入2n個數字,其中,除了有兩個數字是單獨出現外,剩下任何乙個數字出現次數都是偶數個,請寫出演算法找出這兩個數字並輸出
讀入樣例:
81 3 4 5 9 1 4 3
輸出:5 9
思路1:看到這道題目,第一反應就是for迴圈列舉一遍,然後統計每個數字出現的次數,最後輸出出現次數是奇數次的:
mapnum;
for (int i=1;i<=n;i++)
for (int i=1;i<=n;i++)
if (num[arr[i]]==1)
cout<
這樣做,時間複雜度是o(nlogn)的,空間複雜度是o(n)的,已經是乙個不錯的演算法,如果使用雜湊表來寫,時間複雜度可以降低到o(n)。
思路2:先來考慮乙個更簡單的問題,讀入2n+1個數字,其中只有乙個數字出現了1次,剩下的都是偶數次。
這樣子的話,題目被簡化了很多,這個時候怎麼做呢?可以考慮這樣乙個神奇的操作:^
a^a=0,b^a^b^a=0,對於樣例來說(假設沒有9那個數字):1^3^4^5^1^4^3=5,3和3,4和4,1和1互相都^成了0,剩下的5就是唯一單獨出現的那個數字。
當孤立的數字成了兩個的時候,^又能帶來什麼呢,1^3^4^5^9^1^4^3=12
在二進位制下
5=0101 , 9=1001 5^9=0101^1001=1100=12
由異或的性質可以知道,結果裡面兩個位置上的1,說明這兩個數字在這兩位上是不同的,因此,我們可以根據其中任意一位上是0或者1,把所有的數字分成兩撥:
4 5 4……二進位制下第三位是1
1 3 9 1 3……二進位制下第三位是0
這樣,再對他們分別進行異或,就能得到結果5和9!
int num=0;
for (int i=1;i<=n;i++) num^=arr[i];
int now=1;
for (int i=1;;i++)
int ans1=0,ans2=0;
for (int i=1;i<=n;i++)
if ((arr[i]&now)>0)
ans1^=arr[i];
else
ans2^=arr[i];
cout<
每日一練 0001找出單獨出現的數字
描述 給出n個數字。其中僅有乙個數字出現過一次,其他數字均出現過兩次,找出這個出現且只出現過一次的數字。要求時間和空間複雜度最小。輸入輸入多個數字,每個數字以空格分開。數字數量 n 20,輸入數字的最大值小於 256.輸出輸出內容為只出現過唯一一次的數字 輸入樣例10 10 11 12 12 11 ...
每日一題 9 請找出陣列中兩個只出現一次的數字
題目描述 乙個整形陣列裡除了兩個數字之外,其他的數字都出現了兩次。請寫程式找出這兩個只出現一次的數字。例如陣列為,找出數字7和9。思路對陣列內每個數進行按位異或 因為相同的數字異或後為0,陣列中只有兩個數字出現一次,其餘都出現兩次,異或出來的結果一定不為0 得到異或出來的數字的二進位制位第乙個為1的...
每日一題 37 兩個佇列實現棧
題目來自劍指offer 題目 兩個佇列實現棧 思路 乙個佇列存資料,另乙個佇列作為轉存資料的臨時佇列。注意 哪個佇列存資料不定,那個佇列作為臨時佇列也不定。壓棧時 找到乙個有資料的佇列,放入資料。如果兩個佇列都為空,則隨便找乙個佇列存資料。出棧時 找到那個存資料的佇列,設其資料個數為n。1 對數列執...