TopK問題詳解

2021-07-02 15:59:55 字數 1260 閱讀 2931

1. 基本topk問題描述:從1百萬個數中找出最大(或最小)的5個數

看到這個問題,很多同學的第一反應會是:排序。那麼,選擇哪種排序方法呢,有同學說:快排,將所有數排序後,再選出最大的5個。雖然快排確實能解決這個問題,但是需要對1百萬個數排序,但我們僅僅需要其中的5個。那麼,有更好的方法嗎?

還記得我們之前介紹的選擇類排序演算法嗎?我們說過,選擇類排序演算法,最大的特點就是能在一輪排序後獲得最終排序序列中位於指定位置的元素。比如,第一輪選擇類排序,就能選出最大(或最小)的數。可見,只需進行5輪選擇類排序即可達到題目要求。而使用快排,需要log(1百萬)輪partion。

選擇類排序,我們介紹了兩種:簡單選擇排序和堆排序。那麼,選哪個呢?當然是堆排序,時間效率更高。

問題的答案顯而易見了:

第一步:建大頂堆,建堆後,最大元素位於堆頂。

第二步:將堆頂元素與最後乙個元素交換,調整堆頂。重複該過程四次。位於儲存堆的陣列倒數的五個數,即為最大的五個數。

我們通過乙個例子,來說明topk問題。從10,6,9,8,7,5中選出最大的兩個元素的過程如下圖:

同學們看到這裡是否已經明白了怎樣用堆這種資料結構來解決topk問題呢?下面我們來看一道更具挑戰性的問題:

2. 有10個檔案,放在10臺機器上。每個檔案中有1百萬個數,要求選出這1000萬個數中最大的5個數。

只要最大的5個數,這5個數一定是在每個檔案中最大5個數合起來共50個數中。

先從每個檔案中選出最大的5個數(堆排序),然後都傳到一台機器上處理。問題變成,選出10個有序序列中最大的5個數。也就是有序序列的合併問題。

經過以上分析,我們找到了解決方法。

第一步,用「大頂堆」從10個檔案中分別選出最大的5個,傳到一台機器上

第二步,將10個序列合併。可以設10個指標指向每個序列,每次通過9次比較選出最大的1個。共需要進行5輪,比較45次,即可選出最大的5個。

怎麼樣,同學們明白了嗎?如果明白了,我們再來增加難度,看題 3. 有10個檔案,放在10臺機器上。每個檔案中有1百萬個數,要求選出這1000萬個數中最大的50個數。 第三道題目與第二道題目非常相似,區別僅在於從5個數變成了50個數。那有什麼區別呢?第一步,與問題二完全相同,還是利用「大頂堆」進行。問題在於第二步,我們知道,有10個有序序列,從10個數中選出最大的,需要9次比較。現在,需要50個數,那就是450次比較。有沒有更好的方法呢。當然,答案就是「敗者樹」。什麼是敗者樹,為什麼要用敗者樹呢?

請看:敗者樹

Top K問題詳解

最容易想到的方法是將資料全部排序,然後在排序後的集合中進行查詢,最快的排序演算法的時間複雜度一般為o nlogn 如快速排序。但是在32位的機器上,每個float型別佔4個位元組,1億個浮點數就要占用400mb的儲存空間,對於一些可用記憶體小於400m的計算機而言,很顯然是不能一次將全部資料讀入記憶...

TopK問題詳解

問題描述 本文 以在面試題40.最小的k個數中可提交 在無序陣列 nums 中,找出最小 或最大 的 k 個數。例如,輸入 4,5,1,6,2,7,3,8 這8個數字,則最小的4個數字是1 2 3 4。直接將陣列進行排序,然後取出前 k 個元素即可。這是最容易想到的。略。直接排序需要對整個陣列 n ...

Top K 演算法詳解

假設目前有一千萬個記錄 這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。乙個查詢串的重複度越高,說明查詢它的使用者越多,也就是越熱門。請你統計最熱門的10個查詢串,要求使用的記憶體不能超過1g。問題解析 要統計最熱門查詢,首先就是要統計每個query出現的次數,然後根據...