尋找最大的K個數

2022-06-05 18:06:06 字數 1072 閱讀 2640

給你n個數,讓你找出其中最大的

k個數。

解法1

很多人上來就對其進行排序,選用不同的排序方法有不同的時間複雜度,這裡我們假設使用了最快的快排,時間複雜度為o(n*logn)

。通過排序我摘出前

k大的數。

但也許快排不是最優的,我們只找最大的k

個數,何必要對所有的數進行排序,我們只需要進行區域性排序即可,時間複雜度大概是

o(n*k)

。但快排和區域性排序誰優誰劣是並不是一定的,當k

大於某個數值時快排的優勢就顯現出來了,大概是

logn

吧。解法2

這個方法是基於快排的,但不是完整的快排。

回憶一下快排,在每一步中,都是將帶排資料分成兩部分,其中一部分中的任何乙個都比另一部分中的任何都大,然後遞迴排序。

在這裡,我們只要在遞迴過程中選包含最大的k

個數的部分進行完整的快排,而對於其他的部分只進行快排的一部分。

關於使用快排求第k

大數的方法參見其他博文

。在這個基礎上,只需要做小小的改進就可以完成尋找最大k

個數的功能了,時間複雜度

o(n)

解法3

以上的兩個方法都需要對所有資料遍歷多次,如果資料量太大,都沒辦法全部裝進記憶體了,這時候我們何談排序。

其實我們有更優的解決方法,我們可以先拿出k

個元素建乙個最小堆,然後遍歷其他元素,與堆頂的元素進行比較。

有三種情況:

1  與堆頂元素相同,跳過。

2  小於堆頂元素,跳過。根據最大堆性質,堆頂是堆中最小的元素,既然都比最小的都小,  肯定不屬於最大的

k個元素了。

3  大於堆頂元素, 將其與堆頂元素對換, 然後維護這個堆。

結果遍歷所有元素後,我們都得到儲存最大k

個數的堆,也就到達了我們的目的。

尋找最大的K個數

方法一 改進的快速排序 分割槽時,根據數p將陣列分為兩部分,設大於p的數個數為a,小於p的數的個數為b。如果,a k,則從這a個數取最大的k個數,若a時間複雜度是o nlogk include includevoid swap float a,float b int fun float n,int ...

尋找最大的K個數

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

尋找最大的K個數

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