在乙個陣列中尋找最大的k個數,我們首先說一種非常簡單的方法,利用快速排序中的分割演算法,即我們經常看見的partition。這個函式會返回乙個 int 型別的值,這個值代表的是前一半數字和後一半數字的分割點,前一半數字都小於等於後一半數字(遞增排序),所以,我們只要找到相對應的分割點,即可以找到最大的k個數,或者最小的k個數,這就是利用線性方法可以完成任務的方法。
首先,給出函式宣告:
int dutpartition(int*, int, int);
void dutfindmaxkinarray_1(int*, int, int);
源**如下:
/*經典的快排分割程式*/
int dutpartition(int* a, int low, int high)
a[low] = pivot;
/*最終返回「中點」位置*/
return low;
}/*這裡的解法很簡單,就是一直尋找index的最終位置,找到了就可以跳出迴圈了*/
void dutfindmaxkinarray_1(int* a, int size, int k)
/*輸出最大的k個值*/
for (int i = size - k; i < size; ++i)
cout << a[i] << " ";
cout << endl;
}
經過分析**,我們可以知道,這個方法會改變原來陣列中數字的順序。假如說,不允許改變原來的結構呢?那麼,我們可以利用最小堆解決topk的問題,最小堆的性質是堆頂元素是堆中元素值最小的乙個,所以,我們只要判斷下當前的堆頂元素是否比陣列中元素小就可以了,如果是小,那麼替換並重新調整堆,如果是大,那麼不用理會這個元素。
由於 stl 中 multiset 是利用紅黑樹實現的,可以實現堆的性質,所以,我們可以利用 multiset 來解決這個問題,這種方法得到的時間複雜度是o(nlogn)
函式宣告如下:
/*2.5 尋找最大的k個數*/
typedef std :: multiset> intset;
typedef std :: multiset> :: iterator setinterator;
void dutfindmaxkinarray_2(const std :: vector&, intset&, int);
源**如下:
/*第一種解法不好的地方在於它改變了陣列中原來數的順序*/
/* *第二種解法利用最小堆的思想尋找topk,是經典的大資料解題方法,
*網路上很多類似的解釋,這裡,不做過多的解釋
*/void dutfindmaxkinarray_2(const std :: vector& data, /*模擬最小堆*/intset& leastnums, int k)
else
}}}
《程式設計之美》2 5尋找最大的K個數
問題 有很多個無序的數 假設為n個 怎麼選出其中最大的k個數?kay s word kay的理解 很多 好多好多,無法儲存,因此首先排除了對輸入數排序的解法,而採用小容量陣列整理大的輸入資料,即 開大小為k的陣列,通過遍歷n個輸入陣列,每遍歷乙個數num,檢查k陣列的最小數,如果比num小,則用nu...
程式設計之美2 5 尋找最大的K個數
問題 從一組數中選出其中最大的k個數,當這組數的個數為幾百 幾百萬 幾百億時分別適合採用哪些演算法?個數為幾百時,使用順序統計法 看演算法導論第9章 演算法思想是對輸入陣列進行遞迴劃分,一邊的資料小於選定數,另一邊的資料大於等於選定數。但和快速排序不同的是,快速排序會遞迴處理劃分的兩邊,而順序統計法...
程式設計之美 2 5 尋找最大的K個數
今天看演算法分析是,看到乙個這樣的問題,就是在一堆資料中查詢到第k個大的值。名稱是 設計一組n個數,確定其中第k個最大值,這是乙個選擇問題,當然,解決這個問題的方法很多,本人在網上搜尋了一番,查詢到以下的方式,決定很好,推薦給大家。所謂 第 前 k大數問題 指的是在長度為n n k 的亂序陣列中s找...