第一次遇到堆排序的问题,记录一下
什么是堆排序
什么是堆呢?
所谓的的堆就是一个完全二叉树树中每个结点的值都不小于(或不大于)其左右孩子的值 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。
优先队列
priority_queue<Type, Container, Functional>;
Tyep是我们存放在堆里的元素。
Container是实现堆的容器,一般是数组vector
Functional是比较方式/比较函数/优先级
默认的容器是vector,默认的比较方式是大顶堆less<type>
默认元素还可以自定义,参考这篇题解347. 前 K 个高频元素 - 力扣(LeetCode)
这里采用仿函数写法
//大顶堆
struct myComparison
{
bool operator () (fruit f1,fruit f2)
{
return f1.price < f2.price;
}
};
为什么可以将这里居然可以将map这个哈希表的元素压入pair
在这个代码片段中,实际上并不是将整个unordered_map
压入pair
,而是将unordered_map
中的键值对(key-value
对)压入priority_queue
。unordered_map
的迭代器返回的是键值对类型,即std::pair<const key_type, mapped_type>
,因此可以直接使用这些迭代器返回的值。
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
//sort(nums.begin(), nums.end());
unordered_map<int, int>map;//两个int分别是元素和出现的次数
for (int i = 0; i < nums.size(); i++)
{
map[nums[i]]++;
}
//2.利用优先队列,将出现次数排序
//自定义优先队列的比较方式,小顶堆
struct mycomparison {
bool operator()(pair<int, int>& p1, pair<int, int>& p2) {
return p1.second > p2.second;//小顶堆是大于号
}
};
//创建优先队列
priority_queue<pair<int, int>, vector<pair<int, int>>, mycomparison>q;
//遍历map中的元素
//1.管他是啥,先入队列,队列会自己排序将他放在合适的位置
//2.若队列元素个数超过k,则将栈顶元素出栈(栈顶元素一定是最小的那个)
for (auto& c : map)
{
//很奇怪,这里居然可以将map这个哈希表的元素压入pair
q.push(c);
if (q.size() > k)
{
q.pop();
}
}
//将结果导出
vector<int>res;
while (!q.empty()) {
res.emplace_back(q.top().first);
q.pop();
}
return res;
}
};