前K个最大的数

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;
}


转载于:https://my.oschina.net/qxztry86/blog/162764

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值