一、使用场景
堆在实现上是完全二叉树,堆可以用于构造优先队列,堆可以用于排序,排序算法相对稳定。
二、常见问题
堆常用于解决TOPK问题,并不需要完全排序,例如以下问题:
/*
解决思路:
1. 将arr构造成最小堆,然后进行堆排序
2. 取出前K个值便可,不需要完全排序
*/
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k) {
vector<int> ret;
for (int i=0; i<k; i++)
{
int n = arr.size();
//最后一个非叶节点为arr[n/2-1], 从该节点开始进行调整
for(int j=n/2-1; j>=0; j--)
{
if(arr[j] > arr[2*j+1])
{
int t = arr[j];
arr[j] = arr[2*j+1];
arr[2*j+1] = t;
}
if(2*j+2 <= n-1 && arr[j] > arr[2*j+2])
{
int t = arr[j];
arr[j] = arr[2*j+2];
arr[2*j+2] = t;
}
}
//得到最大值;
ret.push_back(arr[0]);
arr[0] = arr[n-1];
arr.pop_back();
}
return ret;
}
};
以上时间复杂度太大,在数据量较大时,无法通过测试,下面使用标准库中内置的优先队列,进行堆排序,获取topK。
class Solution {
public:
vector<int> getLeastNumbers(vector<int>& arr, int k)
{
vector<int> ans;
priority_queue<int,vector<int>,greater<int>> q;
for(auto a:arr)
{
q.push(a);
}
for(int i=0;i<k;i++)
{
int n=q.top();
ans.push_back(n);
q.pop();
}
return ans;
}
};