小灰一邊回憶一邊講述起當時面試的情景......程序員
題目:一個無序數組裏有99個不重複正整數,範圍從1到100,惟獨缺乏一個整數。如何找出這個缺失的整數?面試
解法一:算法
建立一個HashMap,以1到100爲鍵,值都是0 。而後遍歷整個數組,每讀到一個整數,就找到HashMap當中對應的鍵,讓其值加一。數組
因爲數組中缺乏一個整數,最終必定有99個鍵對應的值等於1, 剩下一個鍵對應的值等於0。遍歷修改後的HashMap,找到這個值爲0的鍵。3d
假設數組長度是N,那麼該解法的時間複雜度是O(1),空間複雜度是O(N)。cdn
解法二:blog
先把數組元素進行排序,而後遍歷數組,檢查任意兩個相鄰元素數值是不是連續的。若是不連續,則中間缺乏的整數就是所要尋找的;若是全都連續,則缺乏的整數不是1就是100。排序
假設數組長度是N,若是用時間複雜度爲O(N*LogN)的排序算法進行排序,那麼該解法的時間複雜度是O(N*LogN),空間複雜度是O(1)。it
解法三:io
很簡單也很高效的方法,先算出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—————
喜歡本文的朋友們,歡迎長按下圖關注訂閱號程序員小灰,收看更多精彩內容