問題描述:有 n (n>1000000)個數,求出其中的前k個最小的數(又被稱作topk問題)將n個數進行完全排序,從中選出排在前k的元素即為所求。有了這個思路,我們可以選擇相應的排序演算法進行處理,目前來看快速排序,堆排序和歸併排序都能達到**o(nlogn)**的時間複雜度。
可以採用資料池的思想,選擇其中前k個數作為資料池,後面的n-k個數與這k個數進行比較,若小於其中的任何乙個數,則進行替換。這種思路的演算法複雜度是o(n*k).
剩餘的n-k個數與前面k個數比較的時候,是順序比較的,演算法複雜度是k。
大根堆維護乙個大小為k的陣列,目前該大根堆中的元素是排名前k的數,其中根是最大的數。此後,每次從原陣列中取乙個元素與根進行比較,如小於根的元素,則將根元素替換並進行堆調整(下沉),即保證大根堆中的元素仍然是排名前k的數,且根元素仍然最大;否則不予處理,取下乙個陣列元素繼續該過程。該演算法的時間複雜度是o(n*logk),一般來說企業中都採用該策略處理topk問題,因為該演算法不需要一次將原陣列中的內容全部載入到記憶體中,而這正是海量資料處理必然會面臨的乙個關卡。
利用快速排序的分劃函式找到分劃位置k,則其前面的內容即為所求。該演算法是一種非常有效的處理方式,時間複雜度是o(n)(證明可以參考演算法導論書籍)。對於能一次載入到記憶體中的陣列,該策略非常優秀。
**實現:基於快排和堆排的topk演算法
(1)可以避免對所有資料進行排序,只排序部分;
(2)氣泡排序是每一輪排序都會獲得乙個最大值,則k輪排序即可獲得topk。
(1)堆:分為大頂堆(堆頂元素大於其他所有元素)和小頂堆(堆頂其他元素小於所有其他元素)。
(2)我們使用小頂堆來實現。
(3)取出k個元素放在另外的陣列中,對這k個元素進行建堆。
(4)然後迴圈從k下標位置遍歷資料,只要元素大於堆頂,我們就將堆頂賦值為該元素,然後重新調整為小頂堆。
(5)迴圈完畢後,k個元素的堆陣列就是我們所需要的topk。
(1)比如有10億的資料,找處top1000,我們先將10億的資料分成1000份,每份100萬條資料。
(2)在每乙份中找出對應的top 1000,整合到乙個陣列中,得到100萬條資料,這樣過濾掉了999%%的資料。
(3)使用快速排序對這100萬條資料進行」一輪「排序,一輪排序之後指標的位置指向的數字假設為s,會將陣列分為兩部分,一部分大於s記作si,一部分小於s記作sj。
(4)如果si元素個數大於1000,我們對si陣列再進行一輪排序,再次將si分成了si和sj。如果si的元素小於1000,則我們需要在sj中獲取1000-count(si)個元素的,也就是對sj進行排序
(5)如此遞迴下去即可獲得top-k。
Top K 演算法詳解
假設目前有一千萬個記錄 這些查詢串的重複度比較高,雖然總數是1千萬,但如果除去重複後,不超過3百萬個。乙個查詢串的重複度越高,說明查詢它的使用者越多,也就是越熱門。請你統計最熱門的10個查詢串,要求使用的記憶體不能超過1g。問題解析 要統計最熱門查詢,首先就是要統計每個query出現的次數,然後根據...
大資料Top K 總結
目錄 top k 問題 1億個數字中找出最大或最小的前100個數字 方法1 全部排序 方法2 區域性淘汰法 插入容器後的操作 區域性淘汰法的去重 方法3 分治法 分治 快排劃分 分治 排序 分治 堆排序 合併結果 方法4 hash法 bitmap 計數排序 方法5 最小堆 實際場景 1 單機 單核 ...
面試 演算法 Top K
top k問題是面試時手寫 的常考題,某些場景下的解法與堆排和快排的關係緊密,所以把它放在堆排後面講。下面先來還原一下top k考試常見的套路。你正緊張地坐在小隔間裡,聽著越來越近的腳步聲,內心忐忑,猶如兔脫。推門聲呷然而起,你扭頭一看,身體已不由自主起立,打量著眼前來人,心裡一陣竊喜 還好,面善。...