演算法題 求陣列中最小的k個數

2021-06-23 02:37:58 字數 1195 閱讀 3755

題目:輸入n個整數,找出其中最小的k個數

《劍指offer》給出了兩種實現演算法:

演算法1:採用partition+遞迴法,該演算法可以說是快速排序和二分查詢的有機結合。演算法的時間複雜度為o(n),缺點在於在修改partition的過程中會修改原陣列的值。

演算法2:採用top-k演算法。如果要找最小的k個數,我們才用乙個含有k個值的大頂堆;如果要找最大的k個數,我們採用小頂堆。該演算法的時間複雜度為o(nlogk),是一種比較好的演算法,啟發於堆排序。

這裡我說明下《劍指offer》在實現上我認為不足的地方:書中用乙個基於紅黑樹的multiset容器來模擬堆,但實際上紅黑樹是一棵bst,而堆不一定滿足bst的特徵。雖然用紅黑樹能得到結果,但是我認為並不是最好的,其實stl中有乙個容器介面卡priority_queue,其底層的實現資料結構就是乙個堆,由於堆是一棵完全二叉樹,所以陣列的下標與標準定義的左右孩子相對應,所以用基於vector容器的priority_queue的大頂堆我們能夠獲取最小的k個數。

我的實現**(用priority_queue):

int* getmink(int *arr,int n,int k,int *result)//用priority_queue實現乙個堆

multiset>mset(arr,arr+k);//用降序排序

int i=k;

multiset>::iterator iter;

for(;i測試**:

int main()

; int n=sizeof(arr)/sizeof(int);

cout<

copy(arr,arr+n,ostream_iterator(cout," "));

cout<>k)

cout<

測試結果如下:

參考文獻------------《劍指offer》

求陣列中最大的K個數

最容易想到的就是迴圈遍歷陣列k次求出最大的k個數。這個演算法有許多的缺點 第一點就是速度不夠,它的時間複雜度中o k n 當陣列很大時,不能全部載入到記憶體中,這個演算法就不可行了。這道題目還有兩種比較優的解法 1.我們可以利用快速排序中的思想,快速排序每次都把資料分為兩個部分,第一部分大於某個數,...

查詢陣列中最小k個數

思路 可採用大頂堆來實現 維護乙個規模為k的大頂堆。從前往後掃瞄陣列元素 若大頂堆的size小於k,則把當前元素插入大頂堆中 若小於k,若當前元素小於堆頂元素,則刪除堆頂元素,插入當前元素。考慮到從頭實現乙個大頂堆比較麻煩,這裡使用treeset容器,它提供有序的set。treeset底層實際使用的...

找出陣列中最小的k個數

leetcode 面試題40.最小的k個數 快速排序,時間複雜度為nlogn,然後前k個元素就是最小的k個數 class solution 原理也是快速排序的原理,只不過增加了停止條件。不用完全排序而已。class solution int label quicksort arr,0,arr.len...