求最大k个数

这里k==100


#include <cstdio>

#include <string>
#include <cmath>
#include <queue>
#include <iostream>
using namespace std;

int main()
{
    //默认是大顶堆
    priority_queue<int> q;
    int n, t;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &t);
        q.push(t);
    }
    bool first=true;
    int cnt=100;
    while (!q.empty() && cnt>0)
    {
        if(first)
        {
            printf("%d", q.top());
            first=false;
        }
        else
        {
            printf(" %d", q.top());
        }
        q.pop();
        --cnt;
    }
    printf("\n");
    return 0;
}


前面算法由于queue保存了所有的数据,所以比较速度和内存占用比较大,还可以优化。
思想是,只保留最大的k个。 这样就要用最小堆,每次入队后,把最小的删除。 最后倒序输出
优化后代码如下:

#include <cstdio>

#include <string>
#include <cmath>
#include <queue>
#include <list>
#include <iostream>
using namespace std;

const int cnt=100;
int main()
{
    //默认是大顶堆, 改为最小堆。 小的在前
    priority_queue<int, vector<int>, greater<int> > q;
    int n, t;
    scanf("%d", &n);
    for(int i=0; i<n; i++)
    {
        scanf("%d", &t);
        q.push(t);
        // 超过100个,就把前面小的剔除,剩余的就是我们要的大的100个,每次插入就只要跟最大的100个比较
        if(q.size()>cnt)
            q.pop();
    }
    // 由于目前小的在前,大在后,所以需要倒序。先塞入到vector里面
    vector<int> res;
    while (!q.empty()) {
        res.push_back(q.top());
        q.pop();
    }
    //倒序输出
    for(vector<int>::reverse_iterator it = res.rbegin(); it!=res.rend(); ++it)
    {
        if(it==res.rbegin())//first one
            printf("%d", *it);
        else
            printf(" %d", *it);
    }
    printf("\n");
    return 0;
}

image
发现速度没提高多少,但是内存小了很多。

posted on 2020-08-06 16:51  katago  阅读(267)  评论(0编辑  收藏  举报