topK 问题基本有以下几种:
- 数组前 K 大的 k 和数字
- 数组第 K 大的数字(一个数)
前k大的k个数
样例输入:3 11 15 25 2 3 99 -32 15 94 3 100 256
,其中第一个数是 k,第二个数是 n,后边是n个数。
样例输出:256 100 99
比如要输出 top 10 的数,就用优先队列(小根堆),不断往里push直到size()为 10,然后每次读入一个数 a,跟堆顶元素 top(即目前第10大元素)比较,如果 a<= top,说明 a 不会是 top 10 的数,因为已知 >= 它的就已经有 10 个了,所以只有当 a > top 时,才会往堆里 push。
#include <iostream>
#include <vector>
#include <queue>
#include <functional> // std::greater
using namespace std;
/*
3 11 15 25 2 3 99 -32 15 94 3 100 256
256 100 99
*/
struct cmp {
bool operator()(int a, int b) {
return a > b;
}
};
int main() {
int k, n, a; // 每次读到a里
cin >> k >> n;
// 小根堆
priority_queue<int, vector<int>, greater<int>> pq; // 或者 cmp
for (int i = 0; i < n; ++i) {
cin >> a;
if (i < k)
pq.push(a);
else if (a > pq.top()) {
pq.pop();
pq.push(a);
}
}
vector<int> res;
for (int i = 0; i < k; ++i) {
res.push_back(pq.top());
pq.pop();
}
for (auto ite = res.rbegin(); ite != res.rend(); ++ite)
cout << *ite << ' ';
}
注意这里 priority_queue<int, vector<int>, greater<int>> pq;
第三个参数是结构体,这里默认less<int>
,所以传入的是不带括号的,并且不能传入lambda表达式。
template<class _Ty,
class _Container = vector<_Ty>,
class _Pr = less<typename _Container::value_type> >
class priority_queue
{
...
}
而 sort
函数第三个参数是 less()(即要传入的是表达式,所以不写括号也是不行的,会提示 “将类型用作表达式非法”),调用是要写括号:sort(v.begin(), v.end(), greater<int>()); // 降序
,同时也可以传入lambda表达式:如 sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // 降序
。
显式传入 greater<int>
或者 greater<int>()
需要头文件 functional
。
第k大的数
使用快排思想,参考 https://blog.csdn.net/Bob__yuan/article/details/100145469。