概述
c++ STL中的優先隊列與普通隊列相似,需要頭文件#include <queue>
優先隊列可以看成進行按優先級排列的隊列
,它本質是一個堆實現的。
優先隊列的定義形式爲:
priority_queue<Type, Container, Functional>
舉例:
//大頂
priority_queue <int,vector<int>,less<int> >q; //less<int>可以省略,默認大頂
//小頂
priority_queue <int,vector<int>,greater<int> > q;
優先隊列與普通隊列具有相似的操作,如:
top 訪問隊頭元素
empty 隊列是否爲空
size 返回隊列內元素個數
push 插入元素到隊尾
pop 彈出隊頭元素
應用
leetcode題215:數組中的第K個最大元素
在未排序的數組中找到第 k 個最大的元素。請注意,你需要找的是數組排序後的第 k 個最大的元素,而不是第 k 個不同的元素。
示例 1:
輸入: [3,2,1,5,6,4] 和 k = 2
輸出: 5
示例 2:
輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4
輸出: 4
說明:
你可以假設 k 總是有效的,且 1 ≤ k ≤ 數組的長度。
解答:
思路:
// 1 使用堆,可以使用優先隊列 priority_queue來存放數據
// 2 維護優先隊列(大頂堆)的大小爲 k ,堆頂就是第 k 個最大的數
// 3 注意:當堆的大小已經是 k 個的時候,需要注意直接與堆頂判斷決定是否加入堆中,這樣效率高
// 作者:ikaruga
// 鏈接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array/solution/215-by-ikaruga/
// 來源:力扣(LeetCode)
// 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
class Solution {
public:
int findKthLargest(vector<int>& nums, int k)
{
priority_queue<int, vector<int>, greater<int>> pq;//加greater表示是小頂堆
for (auto& n : nums){
//若堆中已有k個元素,且當前元素小於棧頂,則直接跳過
if (pq.size() >= k && pq.top() >= n)
continue;
pq.push(n);
if (pq.size() > k){ //維持k個元素
pq.pop();
}
}
return pq.top();
}
};
leetcode題347 前k個高頻元素
示例 1:
輸入: nums = [1,1,1,2,2,3], k = 2
輸出: [1,2]
示例 2:
輸入: nums = [1], k = 1
輸出: [1]
提示:
你可以假設給定的 k 總是合理的,且 1 ≤ k ≤ 數組中不相同的元素的個數。
你的算法的時間複雜度必須優於 O(n log n) , n 是數組的大小。
題目數據保證答案唯一,換句話說,數組中前 k 個高頻元素的集合是唯一的。
你可以按任意順序返回答案。
————————————————————————————————————
解答:
與上一題相似,主要區別在於這裏的優先隊列要存儲vector< pair<int,int> >,且要按頻率排列。
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> record; //(元素,頻率)
//遍歷數組,錄入頻率
for(int i = 0; i < nums.size(); i++){
record[nums[i]]++;
}
int n = record.size();
//掃描record。維護當前出現頻率最多的k個元素
//最小堆。如果當前元素的頻率大於優先隊列中最小頻率元素的頻率,則替換
//優先隊列中,按頻率排序,所以數據對是(頻率,元素)形式
priority_queue< pair<int,int> , vector< pair<int,int> >, greater< pair<int,int> > > pq;
for(auto iter = record.begin(); iter != record.end(); iter++){
if(k == pq.size()){ //隊列已滿
if(iter->second > pq.top().first){
pq.pop();
pq.push(make_pair(iter->second,iter->first));
}
}
else{
pq.push(make_pair(iter->second,iter->first));
}
}
vector<int> result;
while(!pq.empty()){
result.push_back(pq.top().second);
pq.pop();
}
//更正
reverse(result.begin(), result.end());
return result;
}
};
// 作者:breadhunter
// 鏈接:https://leetcode-cn.com/problems/top-k-frequent-elements/solution/c-xiao-gen-dui-qiu-qian-kda-by-zhengguanyu/
// 來源:力扣(LeetCode)
// 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。