【海量數據處理】如何在大量的數據中找出不重複的整數?

題目描述

在 2.5 億個整數中找出不重複的整數。注意:內存不足以容納這 2.5 億個整數。

解答思路

方法一:分治法

與前面的題目方法類似,先將 2.5 億個數劃分到多個小文件,用 HashSet/HashMap 找出每個小文件中不重複的整數,再合併每個子結果,即爲最終結果。

方法二:位圖法

位圖,就是用一個或多個 bit 來標記某個元素對應的值,而鍵就是該元素。採用位作爲單位來存儲數據,可以大大節省存儲空間。

位圖通過使用位數組來表示某些元素是否存在。它可以用於快速查找,判重,排序等。不是很清楚?我先舉個小例子。

假設我們要對 [0,7] 中的 5 個元素 (6, 4, 2, 1, 5) 進行排序,可以採用位圖法。0~7 範圍總共有 8 個數,只需要 8bit,即 1 個字節。首先將每個位都置 0:

0 0 0 0 0 0 0 0

然後遍歷 5 個元素,首先遇到 6,那麼將下標爲 6 的位的 0 置爲 1;接着遇到 4,把下標爲 4 的位 的 0 置爲 1:

0 0 0 0 1 0 1 0

依次遍歷,結束後,位數組是這樣的:

0 1 1 0 1 1 1 0

每個爲 1 的位,它的下標都表示了一個數:

for i in range(8):
    if bits[i] == 1:
        print(i)

這樣我們其實就已經實現了排序。

對於整數相關的算法的求解,位圖法是一種非常實用的算法。

那麼對於這道題,我們用 2 個 bit 來表示各個數字的狀態:

  • 00 表示這個數字沒出現過;
  • 01 表示這個數字出現過一次(即爲題目所找的不重複整數);
  • 10 表示這個數字出現了多次。

假設有 232 個整數,總共所需內存爲 232*2b=1GB。因此,當可用內存超過 1GB 時,可以採用位圖法來判斷 232 (42.9億左右)個整數。假設內存滿足位圖法需求,進行下面的操作:

遍歷 2.5 億個整數,查看位圖中對應的位,如果是 00,則變爲 01,如果是 01 則變爲 10,如果是 10 則保持不變。遍歷結束後,查看位圖,把對應位是 01 的整數輸出即可。

方法總結

判斷數字是否重複的問題,位圖法是一種非常高效的方法。

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