【劍指offer】異或去重

來源:互聯網
上載者:User

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/27568975


    這篇文章沒有代碼,介紹的是純理論的思路。

    異或是一種基於二進位的位元運算,用符號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。

    瞭解了上面這些,來看看這個,很重要,後面的程式都要用到這個結論:

    對於任意的a,有a^b^c^d^a^k = b^c^d^k^(a^a) = b^c^d^k^0 = b^c^d^k,也就是說,如果有多個數異或,其中有重複的數,則無論這些重複的數是否相鄰,都可以根據異或的性質將其這些重複的數消去,具體來說,如果重複出現了偶數次,則異或後會全部消去,如果重複出現了奇數次,則異或後會保留一個。

    下面來看兩道題目:

     1、1-1000放在含有1001個元素的數組中,只有唯一的一個元素值重複,其它均只出現一次。每個數組元素只能訪問一次,設計一個演算法,將它找出來;不用輔助儲存空間,能否設計一個演算法實現?

    當然,這道題,可以用最直觀的方法來做,將所有的數加起來,減去1+2+3+...+1000的和,得到的即是重複的那個數,該方法很容易理解,而且效率很高,也不需要輔助空間,唯一的不足時,如果範圍不是1000,而是更大的數字,可能會發生溢出。

    我們考慮用異或操作來解決該問題。現在問題是要求重複的那個數字,我們姑且假設該數字式n吧,如果我們能想辦法把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

    這道題到此為止。

    2、一個數組中只有一個數字出現了一次,其他的全部出現了兩次,求出這個數字。

    明白了上面題目的推導過程,這個就很容易了,將數組中所有的元素全部異或,最後出現兩次的元素會全部被消去,而最後會得到該只出現一次的數字。

    該題目同樣可以該為如下情景,思路是一樣的:數組中只有一個數字出現了奇數次,其他的都出現了偶數次。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.