C++ 輸出前K大的數
阿新 • • 發佈:2018-12-14
1:輸出前k大的數
總時間限制:
10000ms
單個測試點時間限制:
1000ms
記憶體限制:
65536kB
描述
給定一個數組,統計前k大的數並且把這k個數從大到小輸出。
輸入
第一行包含一個整數n,表示陣列的大小。n < 100000。 第二行包含n個整數,表示陣列的元素,整數之間以一個空格分開。每個整數的絕對值不超過100000000。 第三行包含一個整數k。k < n。
輸出
從大到小輸出前k大的數,每個數一行。
樣例輸入
10 4 5 6 9 8 7 1 2 3 0 5
樣例輸出
9 8 7 6 5
首先借助了快速排序的思想,一次快速排序之後,存在一個key牌,左邊的數都小於這個key,右邊的數都大於key,所以只要右邊的數的個數剛好等於k那麼就能找到這個數,在對右邊的數進行排序就行
定義arrangeRight為操作使得右邊的數為k,如果右邊的數大於k,那麼對右邊部分遞迴呼叫這個函式
如果右邊的數小於k,那麼對左邊e-j-s個數進行操作,使得右邊的數等於k
最後在對k個數進行排序,時間複雜度是O(n+klogk)
#include<iostream> #include<algorithm> #define N 100010 using namespace std; void swap(int &a, int &b) { int temp = a; a = b; b = temp; } void quicksort(int a[], int s, int e, int k) { // s 是陣列的開始,e是陣列的最後一個元素,k要求的前k個最大值 int m = a[s]; if (s >= e) return; int i = s, j = e; while (i != j) { while (j > i&&a[j] >= m) { j--; } swap(a[i], a[j]); while (j > i&&a[i] <= m) { i++; } swap(a[i], a[j]); } //quicksort(a, s, i - 1); //quicksort(a, i + 1, e); if ((e - j) == k) { // 如果已經有k個數在key的右邊,則目標完成 return; } else if ((e - j) > k) { // 對右邊的從j到e的數進行操作 quicksort(a, j, e, k); } else { // 對從s到j的數 quicksort(a, s, j, e - j - k); } } int main() { int n, k; int a[N]; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); scanf("%d", &k); quicksort(a, 0, n - 1, k); sort(a+n-k, a + n); for (int i = n-1; i >= n-k; i--) { printf("%d\n", a[i]); } return 0; }