日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Top-K问题与多路归并排序

發布時間:2024/1/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Top-K问题与多路归并排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Pro1:尋找前K大數

方法1:K小根堆??后面的值若大于當前根,則替換之,并調整堆

大部分人都推薦的做法是用堆,小根堆。下面具體解釋下:

如果K = 1,那么什么都不需要做,直接遍歷一遍,時間復雜度O(N)。

下面討論K 比較大的情況,比如1萬。

建立一個小根堆,則根是當前最小的第K個數。然后讀入N-K個數,每次讀入一個數就與當前的根進行比較,如果大于當前根,則替換之,并調整堆。如果小,則讀入下一個。

時間復雜度O(N*logK)。

?

方法2:利用快排分區思想:

本題還有一個時間復雜度比較好的做法。在編程之美上提到過該算法。

首先找到最大的第K個數。這個時間復雜度可以做到O(N),具體做法如下(利用快排分區思想):

從N個數中隨機選擇一個數,掃描一遍,比n大的放在右邊,r個元素,比n小的放左邊,l個元素

如果:??a:l = K-1???返回n

???????????b:l > K-1 在l個元素中繼續執行前面的操作。

???????????c:l < K-1??在r個元素中繼續執行前面的操作。

b,c每次只需執行一項,因此平均復雜度大概為:O(n+n/2+n/4...)=O(2n)=O(n)

?

Pro2: K路合并求Top-K

20路已經有序,20路合并 ?求Top500

有 20 個數組,每個數組有 500 個元素,并且是有序排列好的,現在在這 20*500個數中找出排名前 500 的數。

答:

從20個數組中各取一個數,并記錄每個數的來源數組,建立一個含20個元素的大根堆。此時堆頂就是最大的數,取出堆頂元素,并從堆頂元素的來源數組中取下一個數加入堆,再取最大值,一直這樣進行500次即可。

?

Pro3:?K路合并排序

請給出一個時間為O(nlgk)、用來將k個已排序鏈表合并為一個排序鏈表的算法,此處n為所有輸入鏈表中元素的總數。

算法思想:

1. 從k個鏈表中取出每個鏈表的第一個元素,組成一個大小為k的數組arr,然后將數組arr轉換為最小堆,那么arr[0]就為最小元素了;

2. 取出arr[0],將其放到新的鏈表中,然后將arr[0]元素在原鏈表中的下一個元素補到arr[0]處,即arr[0].next,如果 arr[0].next為空,即它所在的鏈表的元素已經取完了,那么將堆的最后一個元素補到arr[0]處,堆的大小自動減1,循環即可。

http://www.programlife.net/stl-priority-queue.html

?

Pro4:?整體有序局部無序問題

一個有100億個元素的整型數組,它的元素是有序的,現在把它分成若干段,每段不超過20個元素,每段的元素個數不等,現在在每段內將這些元素的順序打亂,然后重新將這100億個元素的數組排序,請問時間復雜度最小的算法是什么?并給出時間復雜度。

http://bbs.csdn.net/topics/390252481

http://blog.csdn.net/burningsheep/article/details/8104493

分析:

如果每段長度相等,則可以考慮采用上面的K路歸并,但此處長度不相等,需另行考慮其它方法。

解:(直接插入排序)

假設第1到第5n個數已經有序為sort(5n),那么我們要將5n+1到5n+5這5個數據添加到已排序的數組中,只需要進行插入排序,將這5個數添加進即可。由于分段的長度不超過5,所以第5n+1個數在插入的時候,最多只需要搜索到第5n-4個數就可以了,比較個數不會超過5次。又因為5n+1到5n+5是已經排好序的,所以,后面的數比較次數也不會超過5次(最多比較到前一個插入的位置)。因此,每加入5個數到已排序數組中,時間復雜度是O(5*5),

假設長度為N,每段長不超過K。則每段插入的時間復雜度即為O(K*K)。

而對于以段為單位插入的操作,需要進行N/K次,所以,總的時間復雜度是O(K*K)*O(N/K)=O(NK)

?

Pro5:100億個數,求最大的1萬個數,并說出算法的時間復雜度

建一個堆,先把最開始的1萬個數放進去。以后每進一個,都把最小的趕出來。

上述算法的可選實現工具:自己建立數組進行堆排序、使用優先隊列priority_queue、使用集合set multiset
在最大堆中,根結點的值總是大于它的子樹中任意結點的值。于是我們每次可以在O(1)得到已有的k個數字中的最大值18,但需要O(logk)時間完成刪除以及插入操作。
隊列(queue)維護了一組對象,進入隊列的對象被放置在尾部,下一個被取出的元素則取自隊列的首部。priority_queue特別之處在于,允許用戶為隊列中存儲的元素設置優先級。這種隊列不是直接將新元素放置在隊列尾部,而是放在比它優先級低的元素前面。優先隊列有兩種,一種是最大優先隊列;一種是最小優先隊列;每次取自隊列的第一個元素分別是優先級最大和優先級最小的元素。
在STL中set和multiset都是基于紅黑樹實現的,查找、刪除和插入操作都只需要O(logk)。

?

總結

以上是生活随笔為你收集整理的Top-K问题与多路归并排序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。