今天偶然看到的有趣的問題,有好幾個系列,感受位運算的小魅力。
當然下面的題可以用map來簡單算出,所以下面的題要求時間複雜度為o(n),空間複雜度為o(1)。
乙個陣列中,只有乙個數隻出現一次,其他的數都是成雙成對出現(2次,4次,6次…),求這出現一次的數。比如求的是3。熟悉異或運算的朋友,看到就會說so easy了。
就是利用異或的性質,兩個相同的數異或結果為0,不同為1,同時異或與順序無關,即滿足交換率。
因此利用這個性質,可以對該陣列所有的數進行異或操作,則成雙成對的數異或後結果為0,得到的值就是只出現一次的值。
實現如下:
int getunique(int a)
乙個陣列中,只有乙個數隻出現一次,其他的數都是出現3次,求這出現一次的數。如 求的就是3。由於不再是成雙成對,因此直接異或怕是解決不了了。不怕,還是可以用位運算來計算的,考慮的是二進位制的表示,因為除了乙個數,其他每個數都出現了3次,所以在這一位上對所有數求和後對3取餘後,出現3次的數對3取餘自然為0了,所以結果就是出現一次的數在這一位的值,所以只要累加就可以得到結果了。
說這麼多廢話,直接上個例子比較直觀。
計算過程如下:
0001
0010
0001
0001
0010
0011
+ 0010
------
0044
% 3333
------
0011 =》 3
看懂上面過程就很明確了,這裡int為4個位元組即32位。實現**也很簡單,如下:
int getunique(int a)
}int ans = 0;
for(int i=0; i<32; i++)
return ans;
}
乙個陣列中,只有兩個數只出現一次,其他的數都是成雙成對出現(2次,4次,6次…),求這出現一次的兩個數。比如求的就是4和3。廢話還是有點多,還是用個例子介紹:
1^4
^3^1
^5^5= 4
^3= 7=
0111(2
進製)所以以第三位的值分成兩組:
「第三位為
0的分組」:
「第三位為
1的分組」:
第乙個數為: 7^1
^3^1= 4
^3^1
^3^1= 4
第二個數為: 7^4
^5^5= 4
^3^4
^5^5= 3
**如下:
// 找出x第乙個1出現的位置
int findfirstbit(int x)
return indexbit;
}void solve(int a)
}
求陣列中只出現一次的數字
假設你有乙個用1001個整數組成的陣列,這些整數是任意排列的,但是你知道所有的整數都在1到1000 包括1000 之間。此外,除乙個數字出現兩次外,其他所有數字只出現一次。假設你只能對這個陣列做一次處理,用一種演算法找出重複的那個數字。如果你在運算中使用了輔助的儲存方式,那麼你能找到不用這種方式的演...
陣列中只出現一次的數
首先看看題目要求 陣列 a中,除了某乙個數字 x之外,其他數字都出現了三次,而 x出現了一次。請給出最快的方法找到x。這個題目非常有意思,在本人部落格中有 位操作基礎篇之位操作全面總結 這篇文章介紹了使用位操作的異或來解決 陣列中其他數字出現二次,而x出現一次,找出x。有 這邊文章介紹了分組異或的方...
陣列中只出現一次的數
題目1 乙個陣列中,除了某乙個只出現過一次的數字外,其餘數字均出現過2次,找出這個只出現了一次的數字。思路 分析題幹,發現強調了陣列中數字出現的次數為1和2,則可以想到異或運算,兩個相同的數字異或結果為0,相同的數異或的結果為其本身,且異或運算存在交換律和結合律,即a b a b,b a a b。那...