異或是一種基於二進位制的位運算,用符號xor或者 ^ 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。
異或的性質:滿足交換律和結合律
1、交換律:a^b = b^a;
2、結合律:(a^b)^c = a^(b^c);
3、對於任意的a:a^a=0,a^0=a,a^(-1)=~a。
了解了上面這些,來看看這個,很重要,後面的程式都要用到這個結論:
如果有多個數異或,其中有重複的數,則無論這些重複的數是否相鄰,都可以根據異或的性質將其這些重複的數消去,具體來說,如果重複出現了偶數次,則異或後會全部消去,如果重複出現了奇數次,則異或後會保留乙個。
下面來看兩道題目:
1、1-1000放在含有1001個元素的陣列中,只有唯一的乙個元素值重複,其它均只出現一次。每個陣列元素只能訪問一次,設計乙個演算法,將它找出來;不用輔助儲存空間,能否設計乙個演算法實現?
當然,這道題,可以用最直觀的方法來做,將所有的數加起來,減去1+2+3+...+1000的和,
得到的即是重複的那個數,該方法很容易理解,而且效率很高,也不需要輔助空間,唯一的不足時,如果範圍不是1000,而是更大的數字,可能會發生溢位。
如果我們能想辦法把1-1000中除n以外的數字全部異或兩次,而數字n只異或一次,就可以把1-1000中出n以外的所有數字消去,這樣就只剩下n了。
我們首先把所有的數字異或,記為t,可以得到如下:
t = 1^2^3^4...^n...^n...^1000 = 1^2^3...^1000(結果中不含n)
而後我們再讓t與1-1000之間的所有數字(僅包含乙個n)異或,
便可得到該重複數字n。如下所示:t^(a^2^3^4...^n...^1000) = t^(t^n) = 0^n = n
這道題到此為止。
但是,當這道題這樣變化之後呢:1-1000及n(n為任意整數)放在含有1001個元素的陣列中,最多有乙個元素值重複,其它均只出現一次,求出n的值?
答案:依然可以從上面的兩種方法。只是用異或的時候直接與1^2…^1000異或即可得到結果。
2、乙個陣列中只有乙個數字出現了一次,其他的全部出現了兩次,求出這個數字。
明白了上面題目的推導過程,這個就很容易了,將陣列中所有的元素全部異或,最後出現兩次的元素會全部被消去,而最後會得到該只出現一次的數字。
該題目同樣可以該為如下情景,思路是一樣的:陣列中只有乙個數字出現了奇數次,其他的都出現了偶數次。
面試題 三進製異或
面試題 陣列a中,除了某乙個數字x之外,其他數字都出現了三次,而x出現了一次。請給出最快的方法,找到x。分析 假設該題目修改為 除了某乙個數字x之外,其他數字都出現了兩次,而x出現了一次。則可以把所有數字直接求異或,最終的結果就是x。這個很好理解。而該題目是其他數字都出現了三次,可以想到三進製異或運...
js陣列去重 面試題
首先再講陣列去重之前,先引進乙個小的知識點indexof indexof 方法可返回某個指定的字串值在字串中首次出現的位置,eg如下 var arr 1 2,3 4,5 var index arr.indexof 1 1,3,5 console.log index index 輸出的是0 2 4 v...
面試題 異或經典思維題目
題目 已知陣列中數字兩兩相同,有兩個不同,找出這兩個不相同的數字 解答過程 如果陣列中只有乙個數字的話,那麼我們就可以直接異或就ok了,但是現在有兩個的話就會有點麻煩了,所以就有乙個非常精彩的思想。首先我們將所有的數字進行異或,結果肯定不會為0所以我們將其進行位運算的話一定會有第index位是1,所...