查詢最小的K個數

2021-08-07 10:55:23 字數 1647 閱讀 9519

輸出最小的k個數

方案1:如果輸入的陣列可變,我們可以借助partion部分排序的思想,隨機選k值,經過排序後,k左邊的數都比k小,k右邊的數都比k大,這樣經過排序後,在k左邊的數字就是最小的k個數:

int partion(int*a, int n, int left, int right)

if(left >= right)

int key = a[right];

while (left < right)

a[right] = a[left];

if (left < right&&a[left] >= key)

a[right] = a[left];

}a[left] = key;

return left;

}void getlastnums(int*input, int n, int *out, int k)

int begin = 0;

int end = n - 1;

intindex = partion(input, n, begin, end);

while(index!=k-1)

else

for (int i = 0; i < k; i++)

out[i] = input[i];

}

但是方案一有明顯的限制:我們需要修改輸入的陣列,因為,partion會改變陣列的數字的順序,如果不修改陣列的順序該如何呢?

方案二:適合海量資料的處理

我們先建乙個大小為k個元素資料的容器用來儲存最小的k個數,接下來每次從輸出的n個資料的整數中讀取乙個數,如果容器裡面的元素的個數小於k,直接將輸出的元素插入到容器裡面,如果容器裡面的元素個數已經是k,表明容器已經滿了,此時比較下乙個插入的數字與容器的元素的最大值比較,小,用這個數字替換容器中的最大的元素,如果大,直接拋棄,直到輸入的元素全部插入容器

我們發現容器滿了會做三件事:一是在k個整數中找最大的數,二是有可能在這個容器中刪除最大的數,三:可能要插入乙個新的數字

這時我們很容易想到大堆,堆頂是最大元素,其他的元素都比堆頂要小,取堆頂的元素時間複雜度是o(1),堆的插入和刪除時間複雜度nlgn,如果用二叉樹來做總的效率就是nlgk

但是有個缺點就是插入和刪除都要重新調整堆

我們想到了紅黑樹,紅黑樹的插入,查詢,刪除的效率都是lgn

在stl中set和multiset都是基於紅黑樹實現

#include

#include

#include

#include

#include

using

namespace

std;

typedef

multiset

> inset;

typedef

multiset

> ::iterator setiter;

void _getleasenum(vector

&data, inset&leasenum, int k)

vector

::iterator it = data.begin();//迭代器遍歷輸入的陣列

for (; it < data.end(); it++)

else}}

}

查詢最大的K個數 查詢最小的K個數

使用乙個容器,大小為k 用這個容器來儲存這最大的或者最小的k個數。如果是找最大的k個數,那麼,每次和容器中的最小元素比較,如果最小的元素小於當前元素,那麼刪除這個最小的元素,同時將當前元素插入 如果是找最小的k個數,那麼就和容器中最大的元素比較。同理。容器用哪個呢?容器選擇用set,set本身就是排...

查詢最小的k個數

乙個整型陣列,有n個元素,可以含有重複元素。查詢該陣列中最小的k個數。1 對陣列快速排序,然後從前往後依次挑出最小的k個元素,時間複雜度 nlogn k nlogn 2 設定乙個容量是 k 的臨時陣列,掃瞄目的陣列,如果臨時陣列元素個數小於k,直接填入臨時陣列,如果臨時陣列元素個數大於k,找出臨時陣...

查詢陣列中最小k個數

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