海量數據中的TOPK問題小結

1.利用堆找出最大的K個數程序員

  首先,先理解下用堆找出最大的K個數的經常使用解法,例如問題是「從M(M <= 10000)個數中找出最大的K個數」面試

(1)利用最大堆算法

  創建一個N=M大小的大頂堆,而後輸出根節點以後,將根節點刪除,而後再將剩餘的元素調整成大頂堆;依次重複K次這個過程,最終就找出了K個最大的數。這實質上就是堆排序的過程。這種方法的時間複雜度爲O(K *logM)數據結構

(2)利用最小堆函數

  這是最經常使用的一種方式,首先創建一個N=K大小的小頂堆,這K個元素能夠爲M中元素中的任意K個;咱們假設這K個元素就是最大的K個元素(其中根節點是這K個元素中最小的元素);那麼對於剩下的M-K個元素,咱們逐個與根節點進行對比,spa

若是當前元素大於根節點的元素的話,就將當前的元素與根節點的元素進行交換,而後將堆再次進行進行調整成最小堆,重複這個過程,直到比較完剩下的M-K個元素;那麼最終的小頂堆對應的K個數,必然是M個數中的最大的K個數。這種方法的.net

時間複雜度爲O(M*logK);而且方法2相對方法1而言,所須要的內存空間更小了,方法1創建的堆須要M個元素對應的內存空間,而方法2創建的堆只須要K個元素對應的內存空間,因此在對內存空間有嚴格要求的狀況下,採用方法2會更加好一些。blog

2.海量數據中找出最大的K個數排序

  對於1而言,M這個指不能很大;若是M很大的話(好比M = 40億),就不能直接使用排序來找了。對於這種狀況,通常是利用「hash映射+堆」的過程,這裏的堆是指的方法2,具體以下:內存

將40億個數分紅若干小的部分(分紅多少部分要看題目對內從空間大小的限制),通常是利用哈希函數$h(x) = x% N$,其中N爲分紅的部分數;而後對於每一個小的部分,若是內存能夠一次性讀取的話,則利用堆採用方法2,選取每一個小部分數據中的TOPK個元素,一共

N*K個元素,而後繼續利用堆,採用方法2從這N*K個元素種找出最大的K個元素。

3.找出100億個URL中重複的URL

  (1)對於這類問題,一般採用的的算法思想是「hash映射+哈希表」;大致而言,將100億個URL利用哈希函數分紅N個部分,每一個部分用哈希表進行統計次數,最終找到全部重複的URL。

  (2)利用字典樹。

4.找出20億個數中出現次數最多的數

  解決這類問題的想和3中的法(1)相似。

5.找出40億個非負整數中出現0次、1次...N次的數

  通常找出非負整數中的出現多少次的數,都是利用BItMap

此處只是粗略的總結下,更詳細的總結可參考左神的《程序員代碼面試指南--IT名企算法與數據結構題目最優解》和July的http://www.javashuo.com/article/p-xfezyxuf-gb.html

相關文章
相關標籤/搜索