每天一道算法题(14)——N个降序数组,找到最大的K个数

 题目

      假定有20个有序数组,每个数组有500个数字,降序排列,数字类型32位uint数值,现在需要取出这10000个数字中最大的500个。


思路

      (1).建立大顶堆,维度为数组的个数,这里为20(第一次 插入的是每个数组中最大的值,即第一个元素)。

      (2).删除最大堆堆顶,保存到数组或者栈中,然后向最大堆插入删除的元素所在数组的下一个元素。

      (3).重复第1,2个步骤,直到删除个数为最大的K个数,这里为500.


代码   

#include 
#include 
#include 
using namespace std;

#define ROWS 20
#define COLS 500

int data[ROWS][COLS];

void CreateData()
{
    for(int i=0; i()); //对每一行降序排列
}
//十分重要
struct Node 
{
    int *p;  //指向某个列,因为要放入优先队列中,所以要比较大小,就用结构体封装了下
    bool operator<(const Node &node) const
    {
        return *p < *node.p;
    }
};

void OutMinData( int k)
{
    struct Node arr[ROWS];
    for(int i=0; i queue( arr, arr+ROWS );  //使用优先队列,默认是大堆,此时需要调用node定义中的“<”重载函数

    for( int i=0; i

分析

      (1),压入大顶堆的元素为Node类型。因此创建大根堆时,需要重载“<”函数

      (2).每次弹出最大值,压入新的值时。最多需要调整log(20)次,因此总共时间复杂度为O(500*log(20))

      (3).sort()默认升序排列,因此需要加入仿函数greater

      (4)data[i]+j==&data[i][j]==*(data+i)+j,&data[i]==data+i


扩展

    倘若非已经排序好的元素的同样数组求最大的前k个数。可以建立高度为log(k)的小根堆。遍历所有数组,每次删除根节点即最小的值,加入节点调整堆。时间复杂度为O(10000*log(500))




参考

      1.N个降序数组,找到最大的K个数




转载于:https://www.cnblogs.com/engineerLF/p/5393028.html

你可能感兴趣的:(每天一道算法题(14)——N个降序数组,找到最大的K个数)