1. 程式人生 > >[轉載自知乎——有哪些令人拍案叫絕的演算法?] [侵必付] 關於位運算

[轉載自知乎——有哪些令人拍案叫絕的演算法?] [侵必付] 關於位運算

有一個n個元素的陣列,除了一個元素只出現一次外,其他元素都出現兩次,讓你找出這個只出現一次的元素是幾,要求時間複雜度為O(n)且不再開闢新的記憶體空間。
——————————答案分割線—————————















解法是將所有元素做異或運算,即a[1] XOR a[2] XOR a[3] XOR…XOR a[n],所得的結果就是那個只出現一次的數字,時間複雜度為O(n)。

當時看了答案後就一拍腦瓜,感嘆這個技巧真不錯。然而直到我遇見了這道題的進階版,當時真是恍然大悟拍案叫絕。

進階版:有一個n個元素的陣列,除了兩個數只出現一次外,其餘元素都出現兩次,讓你找出這兩個只出現一次的數分別是幾,要求時間複雜度為O(n)且再開闢的記憶體空間固定(與n無關)。
——————————答案分割線————————


















首先,仿照前面的演算法,把所有元素異或,得到的結果就是那兩個只出現一次的元素異或的結果。

然後,重點來了,因為這兩個只出現一次的元素一定是不相同的,所以這兩個元素的二進位制形式肯定至少有某一位是不同的,即一個為0,另一個為1,找到這一位。

可以根據前面異或得到的數字找到這一位,怎麼找呢?稍加分析就可以知道,異或得到這個數字二進位制形式中任意一個為1的位都是我們要找的那一位,找到這一位就可以了(這很容易)。

再然後,以這一位是1還是0為標準,將陣列的n個元素分成了兩部分,將這一位為0的所有元素做異或,得出的數就是隻出現一次的數中的一個;將這一位為1的所有元素做異或,得出的數就是隻出現一次的數中的另一個。從而解出題目。忽略尋找不同位的過程,總共遍歷陣列兩次,時間複雜度為O(n)。