漫畫算法:找出缺失的整數

小灰一邊回憶一邊講述起當時面試的情景......

題目:一個無序數組裏有99個不重複正整數,範圍從1到100,唯獨缺少一個整數。如何找出這個缺失的整數?

解法一:

創建一個HashMap,以1到100爲鍵,值都是0 。然後遍歷整個數組,每讀到一個整數,就找到HashMap當中對應的鍵,讓其值加一。

由於數組中缺少一個整數,最終一定有99個鍵對應的值等於1, 剩下一個鍵對應的值等於0。遍歷修改後的HashMap,找到這個值爲0的鍵。

假設數組長度是N,那麼該解法的時間複雜度是O(1),空間複雜度是O(N)。

解法二:

先把數組元素進行排序,然後遍歷數組,檢查任意兩個相鄰元素數值是否是連續的。如果不連續,則中間缺少的整數就是所要尋找的;如果全都連續,則缺少的整數不是1就是100。

假設數組長度是N,如果用時間複雜度爲O(N*LogN)的排序算法進行排序,那麼該解法的時間複雜度是O(N*LogN),空間複雜度是O(1)。

解法三:

很簡單也很高效的方法,先算出1+2+3....+100的合,然後依次減去數組裏的元素,最後得到的差,就是唯一缺失的整數。

假設數組長度是N,那麼該解法的時間複雜度是O(N),空間複雜度是O(1)。

題目擴展:一個無序數組裏有若干個正整數,範圍從1到100,其中99個整數都出現了偶數次,只有一個整數出現了奇數次(比如1,1,2,2,3,3,4,5,5),如何找到這個出現奇數次的整數?

解法:

遍歷整個數組,依次做異或運算。由於異或在位運算時相同爲0,不同爲1,因此所有出現偶數次的整數都會相互抵消變成0,只有唯一出現奇數次的整數會被留下。

假設數組長度是N,那麼該解法的時間複雜度是O(N),空間複雜度是O(1)。

題目第二次擴展:一個無序數組裏有若干個正整數,範圍從1到100,其中98個整數都出現了偶數次,只有兩個整數出現了奇數次(比如1,1,2,2,3,4,5,5),如何找到這個出現奇數次的整數?

解法:

遍歷整個數組,依次做異或運算。由於數組存在兩個出現奇數次的整數,所以最終異或的結果,等同於這兩個整數的異或結果。這個結果中,至少會有一個二進制位是1(如果都是0,說明兩個數相等,和題目不符)。

舉個例子,如果最終異或的結果是5,轉換成二進制是00000101。此時我們可以選擇任意一個是1的二進制位來分析,比如末位。把兩個奇數次出現的整數命名爲A和B,如果末位是1,說明A和B轉爲二進制的末位不同,必定其中一個整數的末位是1,另一個整數的末位是0。

根據這個結論,我們可以把原數組按照二進制的末位不同,分成兩部分,一部分的末位是1,一部分的末位是0。由於A和B的末位不同,所以A在其中一部分,B在其中一部分,絕不會出現A和B在同一部分,另一部分沒有的情況。

這樣一來就簡單了,我們的問題又迴歸到了上一題的情況,按照原先的異或解法,從每一部分中找出唯一的奇數次整數即可。

假設數組長度是N,那麼該解法的時間複雜度是O(N)。把數組分成兩部分,並不需要藉助額外存儲空間,完全可以在按二進制位分組的同時來做異或運算,所以空間複雜度仍然是O(1)。

十分鐘後......

以上就是小灰面試的情況......

—————END—————


喜歡本文的朋友們,歡迎長按下圖關注訂閱號程序員小灰,收看更多精彩內容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章