尋找最大的K個數

2021-06-12 17:58:40 字數 1759 閱讀 7053

方法一:

改進的快速排序: 分割槽時,根據數p將陣列分為兩部分,設大於p的數個數為a,小於p的數的個數為b。如果,a>=k,則從這a個數取最大的k個數,若a時間複雜度是o(nlogk)。

#include#includevoid swap(float &a,float &b)

int fun(float n,int left,int right)

else if(n[k]flag)

quicksort(n,flag,tmp+1,right);

else if((right-tmp+1)>num;

cout<<"the array is: "<>a[i];

scanf("%f",&a[i]);

cout<<"k is:"<>flag;

quicksort(a,flag,0,num-1);

for(int j=num-1;j>(num-1-flag);j--)

cout<方法二:

構建容量為k的最小堆,遍歷一遍陣列,剩下的k個即為所求。時間複雜度是o(nlogk)。其中堆進行調整時間為o(logk)

比較:方法二當資料量比較大的時候,比較方便。因為對所有的資料只會遍歷一次。方法一則會多次遍歷陣列,且n個數全部裝入記憶體,當資料量很大比如100億,則方法不適合。

擴充套件:

1.如果需要找出n個數中最大的k個不同的浮點數呢?比如,含有10個浮點數的陣列(1.5,1.5,2.5,3.5,3.5,5,0,- 1.5,3.5)中最大的3個不同的浮點數是(5,3.5,2.5)。

個人覺得除了最後一種方法不行,其他的都可以。因為最後一種需要是正數。

還要注意的是,浮點數的相同應該用fabsf(a-b)<0.00001等類似的方法來判斷。

2. 如果是找第k到第m(0

4. 在實際應用中,還有乙個「精確度」的問題。我們可能並不需要返回嚴格意義上的最大的k個元素,在邊界位置允許出現一些誤差。當使用者輸入乙個query的時候,對於每乙個文件d來說,它跟這個query之間都有乙個相關性衡量權重f (query, d)。搜尋引擎需要返回給使用者的就是相關性權重最大的k個網頁。如果每頁10個網頁,使用者不會關心第1000頁開外搜尋結果的「精確度」,稍有誤差是可以接受的。比如我們可以返回相關性第10 001大的網頁,而不是第9999大的。在這種情況下,演算法該如何改進才能更快更有效率呢?網頁的數目可能大到一台機器無法容納得下,這時怎麼辦呢?

網上答案:答:正如提示中所說,可以讓每台機器返回最相關的k'個文件,然後利用歸併排序的思想,得到所有文件中最相關的k個。 最好的情況是這k個文件在所有機器中平均分布,這時每台機器只要k' = k / n (n為所有機器總數);最壞情況,所有最相關的k個文件只出現在其中的某一台機器上,這時k'需近似等於k了。我覺得比較好的做法可以在每台機器上維護乙個堆,然後對堆頂元素實行歸併排序。

5. 如第4點所說,對於每個文件d,相對於不同的關鍵字q1, q2, …, qm,分別有相關性權重f(d, q1),f(d, q2), …, f(d, qm)。如果使用者輸入關鍵字qi之後,我們已經獲得了最相關的k個文件,而已知關鍵字qj跟關鍵字qi相似,文件跟這兩個關鍵字的權重大小比較靠近,那麼關鍵字qi的最相關的k個文件,對尋找qj最相關的k個文件有沒有幫助呢?

解答:肯定是有幫助的。 qi最相關的k個文件可能就是qj的最相關的k個文件,可以先假設這k個就是,然後根據問題四的解法獲得k',分別和這k個比較,可以用堆進行比較,從而獲得qj最相關的k個文件。由於最開始的k個文件極有可能是最終的k個文件,所以k'和k比較的次數可能並不多。

參考:

尋找最大的K個數

程式設計之美有一道考察多種排序的題目,題目如下 有乙個長度為n的無序陣列,假定其中的每乙個元素都各不相等,求其中最大的k個數。作者對於此題目結合各種排序演算法給出了五種解法思路。解法一 使用快速排序或堆排序對它們元素進行排序,整個排序的時間複雜度為o n lo g2n 然後取出前k個,時間複雜度為o...

尋找最大的K個數

前提條件 有n個無序的數,假定它們各不相等,如何選出其中最大的若干個數 適用於元素數量不多,記憶體中可儲存整個陣列序列。通過快速排序或堆排序對陣列排序,時間複雜度為o n log2n 然後取出前k個數,時間複雜度為o k 總時間複雜度為o n log2n o k 進一步的,可以知道,我們只需要前 k...

尋找最大的K個數

給你n個數,讓你找出其中最大的 k個數。解法1 很多人上來就對其進行排序,選用不同的排序方法有不同的時間複雜度,這裡我們假設使用了最快的快排,時間複雜度為o n logn 通過排序我摘出前 k大的數。但也許快排不是最優的,我們只找最大的k 個數,何必要對所有的數進行排序,我們只需要進行區域性排序即可...