Description
写一个程序找出N个整数里面前K大的整数,输出按照降序排列。
Input
输入有多个测试用例,每个测试用例是两行:
第1行是两个整数N和K,中间用空格隔开(N ≥ K)
第2行有N个整数,每两个数字中间用空格隔开
输入以EOF结束
Output
对于每一个测试用例,输出一行,K个整数,就是它的前K大的整数,按照降序排列输出,每两个数字之间用空格隔开,最后一个数字后面没有空格,有换行。
Sample Input
5 23 2 4 1 5
Sample Output
5 4
Solution
时间复杂度为O(N*lgK)的方法:
1. 建立最大堆
2. 输出堆顶元素
3. 交换堆顶元素和有序部分前面一个位置的元素
4. 调整堆
5. 重复234步骤直到找到k个数
Code
#include<iostream>
using namespace std;
int str[10005];
void adjustHeap(int index, int n) {
int max_num = str[index];
int max_index = index;
if (index * 2 <= n && max_num < str[index * 2]) {
max_index = index * 2;
max_num = str[max_index];
}
if (index * 2 + 1 <= n && max_num < str[index * 2 + 1]) {
max_index = index * 2 + 1;
max_num = str[max_index];
}
if (max_index != index) {
swap(str[index], str[max_index]);
adjustHeap(max_index, n);
}
}
void buildHeap(int n) {
for (int i = n / 2; i >= 1; i--) {
adjustHeap(i, n);
}
}
int main(void) {
int n, k;
int count;
while (cin >> n && cin >> k) {
for (int i = 1; i <= n; i++) {
cin >> str[i];
}
buildHeap(n);
if (k == 1) {
cout << str[1] << endl;
} else {
cout << str[1] << " ";
count = 1;
for (int i = n; i > 1; i--) {
swap(str[1], str[i]);
adjustHeap(1, i - 1);
count++;
if (count == k) {
cout << str[1] << endl;
break;
} else {
cout << str[1] << " ";
}
}
}
}
}