尋找最大的k個數

2022-08-05 09:06:17 字數 1197 閱讀 1106

這個題目是非常經典的乙個題目,解法也有很多,現在就把我已經理解的解法記錄下來。

題目描述

有n個無序的數,它們各不相等,怎樣選出其中的最大的k個數呢?

題目分析:

解法1:

最容易想到的就是把n個數進行排序,然後選擇最大的k個數。排序演算法很多,快速排序和堆排序都是不錯的選擇,他們的複雜度都是ο(n*log2n),然後取出前k個ο(k

),總的時間複雜度可以看成是ο(n*log2n

)在這個解法中,對n個數進行了排序,如果n的數值非常大的話,會很慢。

解法2:

能不能只遍歷一邊n個數就能把最大的k個數選出來呢?答案是可以的。

在解法2中,規定,n個數儲存在陣列array[n]中,我們需要開闢k個數的空間result[k]。遍歷的最終目的是把最大的k個數儲存在result[k]中。每一步的過程是,當遍歷到array[i]時,判斷array[i]是否比result中最小的數大,如果是,則表明,array[i]應該出現在result中(此時假設result中已存滿k個數)。

那麼應該用什麼樣的方式來進行此過程呢?其實這個也比較好想。

解法3:

這個方法是程式設計之美裡講到的。(其實上個解法程式設計之美裡也提到過,不過也是我自己想到的)

這個方法借鑑快排的思路。假設n個數儲存在陣列s中,從s中隨機找到乙個元素x,把陣列分成兩部分sa

和sb,sa

中的元素大於等於x,sb中的元素小於x。此時,

sa中的元素個數小於k,則k個最大的元素為sa中的元素加上sb中的k-|sa|個元素。

sa中的元素個數大於或等於k,則需要返回sa中最大的k個元素。

這時候已經非常明了了,需要用到遞迴的方法來計算method1中的sb中的k-|s

a|個元素以及method2中的s

a中最大的k個元素。這個演算法的時間複雜度為ο(n*log2k

)。其他

可能需要考慮特殊情況。

如果n不是很大,並且都是整數的話,若max為n個數中最大的數,可以開闢int array[max+1],其中儲存數i的個數。都輸進去,需要用到n此,然後從max開始,找到k個最大的數;如果n個數都不相同,可以開闢max+1個bit型的,只用表明存在或不存在。這樣的解法是線性的。但如果不是整數或者max相當大的話這種方法就不好使了。

肯定還有其他更好的解法的,但是因為我現在還沒有掌握,暫時寫到這裡。

尋找最大的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...