求100億個數的中位數

2021-09-12 16:43:45 字數 1419 閱讀 4027

給定100億個無符號的亂序的整數序列,如何求出這100億個數的中位數(中位數指的是排序後最中間那個數)。

乙個無符號整數的大小為4b,則100億個數的大小為40gb,如果記憶體夠大的話可以對這100億個數載入到記憶體中,然後使用堆排序或者快速排序進行排序,取出中位數即可。使用快排時,每次劃分之後只需要比較樞紐值的索引和50億比較,然後只對兩個劃分中的乙個進行遞迴排序即可,而不用整體進行排序。使用堆排時,建立堆之後,需要進行50億次的調整即可。

中位數問題可以看做乙個統計問題,而不是排序問題,無符號整數大小為4b,則能表示的數的範圍為為0 ~ 2^32 - 1(40億),則可以用乙個2^32(4gb)大小的陣列(也叫做桶)來儲存100億個數中每個無符號數出現的次數。遍歷這100億個數,當元素值等於桶元素索引時,桶元素的值加1。當統計完100億個數以後,則從索引為0的值開始累加桶的元素值,當累加值等於50億時,這個值對應的索引為中位數。時間複雜度為o(n)。

如果記憶體的大小小於4gb時(假設記憶體為512m),這時怎麼辦呢?解決方案為使用區間的桶排序,解題思路如下:

(1)如果只有512m的記憶體,則512m記憶體可以裝2^(9 + 10 + 10) = 536,870,912個無符整數,約為5億左右,接著把無符號整數的範圍0~40億劃分為每10個數乙個區間,也就有4億個區間,劃分後第乙個區間0~9,第二個區間10~19,......在記憶體中使用4億個數來儲存100億個數中落在每個區間的整數個數。此時記憶體中還可以存放1億個數,分100次把100億個數載入到記憶體,每次載入1億個,統計落到每個區間的整數個數。

(2)第一步完成統計之後,可以知道落到4億個區間中每個區間的整數個數,然後從最小區間向最大區間開始累加,當累加的數達到50億時,記住這個區間起點位置終點位置(終點 - 起點 + 1 = 10)和沒有加這個區間統計個數時的整數個數

(3)知道第50億個數所落在的區間起點和終點位置後,接著對區間的每個數設定乙個桶(這裡總共為10個桶),用來統計每個數的元素個數。接著對100億個數分20批次進行遍歷,每次載入到記憶體5億個數。

(4)統計完成之後就可以知道落到區間內的每個元素個數,接著對區間的統計個數進行累加,當這個累加值加上(2)中儲存的沒有加上該區間的整數個數等於50億時,該數對應的索引就位中位數。

總結:整個過程需要遍歷100億個數兩次,第一次確定第50億個數所落在的索引區間,第二次確定第50億個數所落在的索引。區間大小是乙個可以優化的值,優化之後可以使得i/o的次數最少。

求100億個數的中位數

1 題目描述 給定100億個無符號的亂序的整數序列,如何求出這100億個數的中位數 中位數指的是排序後最中間那個數 2 解題思路一 乙個無符號整數的大小為4b,則100億個數的大小為40gb,如果記憶體夠大的話可以對這100億個數載入到記憶體中,然後使用堆排序或者快速排序進行排序,取出中位數即可。使...

10 億個數取中位數

10 億個數取中位數 1 取 16 1024 個數,生成乙個 treemap 取得最大值 max 和最小值 min。2 構造乙個1024個元素的計數陣列 t i 對最初的 1024 個數按區間計數 對 min 和 max 進行 1024 個等分,各等分值為 n i 當資料 n a 3 將大於 n 5...

100億個整數,找出中位數

100億個整數,記憶體足夠,如何找到中位數?記憶體不足,如何找到中位數?1 當記憶體足夠時 採用快排,找到第n大的數。隨機選取乙個數,將比它小的元素放在它左邊,比它大的元素放在右邊 如果它恰好在中位數的位置,那麼它就是中位數,直接返回 如果小於它的數超過一半,那麼中位數一定在左半邊,遞迴到左邊處理 ...