異或的妙用

2021-06-07 23:13:44 字數 945 閱讀 2994

給你1-1000個連續自然數,然後從中隨機去掉兩個,再打亂順序,要求只遍歷一次,求出被去掉的兩個數。

這題其實挺為面試者的,因為要求1分鐘內說出解法,且不能使用計算機、紙和筆。如果之前沒有遇到過類似的題目,加上面試時的緊張心情,很難能在那麼短的時間裡想到解決方案,至少我做不到。

好在我有時間,上網看了一下,比較常見的有兩種方法

遍歷被打亂的陣列時,計算value的累加值和value平方的累加值。結合未打亂之前的陣列,這樣就能得出x+y = m與x*x+y*y = n兩個方程,解這組方程即可算出被去掉的兩個數。這種方法比較容易理解,實現起來也比較簡單

這個就麻煩點了。先來說說異或的定義:兩個二進位制位不同的取1。再來說說異或的兩個特性:順序無關 / 對乙個數異或兩次等於沒有異或。順序無關就是說異或的元素可以隨意交換順序,而不會影響結果。異或兩次可以理解為+x和-x。

計算出x^y的值

首先,這兩個陣列(打亂前和打亂後)各自異或,也就是1^2^…^1000,得到兩個異或值。再對這兩個異或值進行一次異或,這樣就得到了x^y的指(重複部分互相抵消了)。

// 其實就是把陣列的所有元素進行異或,重複部分互相抵消

result = 1^2^...^1000^1^2...^1000;

result = 1^1^2^2...^x...^y...^1000^1000;

result = x^y;

獲取計算出的異或值的1所在的位置,並繼續異或

因為x和y是兩個不同的整數,所以這兩個數的異或結果,轉化為二進位制的話,一定在某位是1,假設在第3位。也就是說如果把原始陣列按第3位是否為0進行劃分,就可以分成兩個陣列,每個陣列各包含乙個被抽取的數。如果打亂後的陣列也按這個規則劃分為兩個陣列,這樣就得到了4個陣列,其中兩組是第3位為0,另外兩組是第3位為1。把第3位為0的兩個陣列所有元素進行異或就能得到被抽取的乙個數,同理也就能獲得另外乙個被抽取的數,於是問題解決。

異或 運算的妙用

現有1,1,2,2,3,3,n,n共2n個數,其中各個數字排列的順序是任意的,是雜亂放的,即沒有排序。現在刪除了其中的乙個數剩下了2n 1個數,求刪除的那個數?可能大多數人的第一想法是 用2n個數的總和 n n 1 減去2n 1個數的總和,不錯,想法是正確的。但是,放在計算機中考慮的話,此方法就不太...

C語言 異或 的妙用

異或 位運算符號,相同的位置0,不同的位置1 例 0101 0001 0100 給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。說明 你的演算法應該具有線性時間複雜度。你可以不使用額外空間來實現嗎?例 輸入 2 2 1 輸出 1 輸入 2 3 3...

C語言異或操作的妙用

如果想要交換2個變數,一般的做法是引入第三個變數,例如,這樣2個變數中的值就實現了交換。那能不能不引入其他變數就可以實現變數值的交換呢?答案是肯定的。用異或操作可以實現,有2種實現方法,本質上是一樣的。法1 法2 因為2種方法本質一樣,就方法一進行一下證明。異或操作滿足結合律和交換律,且由異或操作的...