num个有序的整型数组,每个数组的长度都一样,求前k个最大的数。
解法:利用归并排序一趟归并的思想。
时间复杂度O(k*num), 空间复杂度O(k)。
#include <ctime>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <iostream>
using namespace std;
typedef struct
{
int idx;
enum SORT_TYPE{ASC, DESC}STYPE;
}iter;
//num个整型数组,每个数组的长度为size
void preprocess(int **arr, iter *it, int num, int size)
{
for (int i=0; i<num; i++) {
if (arr[i][0] < arr[i][size-1]) {
it[i].idx = size - 1;
it[i].STYPE = iter::ASC;
}else {
it[i].idx = 0;
it[i].STYPE = iter::DESC;
}
}
return ;
}
void find_top_k(int **arr, iter *it, int num, int size, int *ans, int topk)
{
preprocess(arr, it, num, size);
for (int i=0; i<topk; i++) {
int maxNum = INT_MIN;
int pos = 0;
for (int j=0; j<num; j++) {
if ((it[j].idx >= 0 && it[j].idx < size) && maxNum < arr[j][it[j].idx]) {
maxNum = arr[j][it[j].idx];
pos = j;
}
}
ans[i] = maxNum;
if (it[pos].STYPE == iter::ASC) {
it[pos].idx--;
}else {
it[pos].idx++;
}
}
return ;
}
//以下是生成测试数据
int cmp_asc(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
int cmp_desc(const void *a, const void *b)
{
return *(int *)b - *(int *)a;
}
void test_data(int **arr, int num, int size)
{
srand(int(time(NULL)));
cout << "测试数据:" << endl;
for (int i=0; i<num; i++) {
cout << "数据 " << i << ": ";
for (int j=0; j<size; j++) {
arr[i][j] = rand() % 10000;
}
if (rand() % 2) {
qsort(arr[i], size, sizeof(int), cmp_asc);
}else {
qsort(arr[i], size, sizeof(int), cmp_desc);
}
for (int j=0; j<size; j++) {
cout << arr[i][j] << "\t";
}
cout << endl;
}
return ;
}
//测试
void test(int **arr, iter *it, int num, int size, int *ans, int topk)
{
find_top_k(arr, it, num, size, ans, topk);
return ;
}
//测试结果
void print(int *ans, int topk)
{
cout << "结果:" << endl;
for (int i=0; i<topk; i++) {
cout << ans[i] << "\t";
}
cout << endl;
return ;
}
int main()
{
int num, size;
while (cin >> num >> size) {
int **p = new int*[num];
for (int i=0; i<num; i++) {
p[i] = new int[size];
}
iter *it = new iter[num];
int topk;
cin >> topk;
int *ans = new int[topk];
test_data(p, num, size);
test(p, it, num, size, ans, topk);
print(ans, topk);
for (int i=0; i<num; i++) {
delete [] p[i];
}
delete [] p;
delete [] ans;
}
return 0;
}