40億個非負整數中找到未出現的數

2021-10-02 23:43:29 字數 1211 閱讀 1451

32位無符號整數的範圍是0 ~ 4 294 967 295,現在有乙個正好包含40億個無符號整數的檔案,所以在整個範圍中必然有未出現過的數。怎麼找到所有未出現過的數?

要求:可以使用最多1gb的記憶體。

高階:記憶體限制10mb,但是只用找到乙個沒出現過的數即可。

常規方法:假設用雜湊表來儲存出現過的數,那麼如果40億個數都不同,則雜湊表的記錄數為40億條,存乙個32位整數需要4b,所以最差情況下需要40億×4b = 160億位元組,大約需要16gb的空間,不符合要求。

思路:

① 使用bit map的方式來表示數出現的情況,申請乙個長度為4 294 967 295的 bit 型別的陣列 bitarr(大約需要 0.5gb記憶體),bitarr上的每個位置只可以表示 0 或 1 狀態。遇到num,就把 bitarr[num] 設定為 1。

② 再次遍歷,bitarr下標為 0 的數就是40億個數中未出現的數。

高階:用分區間的方式處理,只有10mb,但只要求找到其中乙個沒出現過的數。首先,將0~4 294 967 295 分成64個區間,每個區間是67 108 864個數,第0個區間(0 ~ 67 108 863)、第 1 個區間(67 108 864 ~ 134 217 728)…第63 個區間(4 227 858 432 ~ 4 294 967 295)。

第一次遍歷。統計落在每乙個區間上的數有多少。申請長度64的整型陣列

countarr[0…63],countarr[i] 用來統計區間 i 上的數有多少。遍歷40億個數,

根據當前數計算出哪乙個區間上的計數增加。

比如,3 422 552 090,3 422 552 090 / 67 108 864 = 51,所以第51個區間

上的數字增加countarr[51]++,遍歷完後,必然會有乙個區間的計數小於

67 108 864。

在 bitarr[i] 上必然存在乙個沒有被設為1的位置,那麼 67 108 864 * k + i

這就是沒出現的數。

精簡解法:

根據10mb的記憶體限制,確定統計區間的大小,就是第二次遍歷時

bitarr的大小。

利用區間計數的方式,找到計數不足的區間,這個區間肯定有沒出現

的數。對這個區間上的數做bit map對映,再遍歷bit map,找到乙個沒出現的

數即可。

40億個非負整數中找到沒出現的數

要求這裡的非負整數是32位也就是0 2 32 1。最多用1gb的記憶體。如果只能用10mb的空間呢,只需要找到乙個沒有出現的數即可。首先先分析一下,40億個4b約為16gb這裡只用1gb,這裡要求注意是找出沒出現,這就和網頁過濾系統類似,出現與不出現兩個狀態 0和1 那麼我們就可以用bit陣列來確定...

40億個非負整數中找到出現2次的數和所有數的中位數

題目一 32位無符號整數的範圍是0 4294967295,現在有40億個無符號整數,可以使用最多1gb的記憶體,找出所有出現了兩次的數。題目二 記憶體限制在10mb,如何找到這40億個整數的中位數。解法思路 依然bit 陣列的思路,不過這次是雙倍長度了,因為我們除了要記錄這個數字,同時還有記錄他出現...

40億個非負整數中找到出現兩次的數和中位數

問題 現有40億個32位的無符號整數 0 4294967295 可以最多使用1gb,找出出現兩次的數 補充問題 最多用10mb,找到中位數 思路 問題一 可以申請乙個長度為 4294967295 2 的bitmap,用兩個位置表示乙個詞頻,首次遇到數num,則bitarr num2 1 和bitar...