堆排序使用的問題

堆排序使用的方法是一種內部的合併排序,是一種 不穩定的內部排序.不過由於對於top k這一類問題和衍生的問題,即在同時需要處理k個值,所堆排序延伸出的最大堆和最小堆而言優勢明顯.只會需要O(n lgK).的複雜度.


top K問題

給定一組任意順序的數,假設有n個。如何儘快地找到它們的前K個最大的數?

首先,既然是找前K個最大的數,那麼最直觀的辦法是,n個數全部都排序,然後挑出前K個最大數。但是這樣顯然做了一些不必要的事兒。

利用堆這種數據結構

主要步驟如下:

step 1. 隨意選出K個數,挑出這K個數的最小的數。這個過程可以用最小堆完成。

step 2. 在剩下的n – K個數中,挑出任意一個數m,和最小堆的堆頂進行比較,如果比最小堆的堆頂大,那麼說明此數可以入圍前K的隊伍,於是將最小堆的堆頂置爲當前的數m。

step 3. 調整最小堆。時間複雜度爲Olg(K),由於K是constant(常數級別),所以時間複雜度可以認爲是常數級別。

step 4. 重複進行step 2 ~ step 3,直到剩下的n – K個數完成。進行了n –constant次,時間複雜度爲O(n lgK).


問題2:合併k個有序鏈表

在O(N lgK) 時間內合併K個有序鏈表, 這裏N指的是K個鏈表中所有的元素個數。

分析:

這是一道非常經典的面試題,在很多大公司的面試題中,此題頻繁出現。這題也是算法導論的作業題。

這題的思路如下:

1) 在每一個鏈表中取出第一個值,然後把它們放在一個大小爲K的數組裏,然後把這個數組當成heap,然後把該堆建成最小堆。此步驟的時間複雜度爲O(K)

2 )取出堆中的最小值(也是數組的第一個值),然後把該最小值所處的鏈表的下一個值放在數組的第一個位置。如果鏈表中有一個已經爲空(元素已經都被取出),則改變heap的大小。然後,執行MIN-HEAPIFY操作,此步驟的時間複雜度爲O(lg K).

3 ) 不斷的重複步驟二,直到所有的鏈表都爲空。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章