堆

class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int>dl;
for(int i=0;i<nums.size();i++){
dl.push(nums[i]);
}
for(int i=0;i<k-1;i++){
dl.pop();
}
return dl.top();
}
};

思路:1.记录词和词频对应关系用map,map的first是key,second是value 2.处理多次最大元素问题使用优先队列(默认大根堆)
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
vector<int>ans;
priority_queue<pair<int,int>>dl;
map<int,int>mp;
for(int i=0;i<nums.size();i++){
mp[nums[i]]++;
}
for(auto i:mp) {
dl.push({i.second,i.first});//词频,词
}
for(int i=0;i<k;i++){
ans.push_back(dl.top().second);
dl.pop();
}
return ans;
}
};


优先队列的自定义排序
#include <iostream>
#include <queue>
using namespace std;
// 全局比较函数:返回 true 表示 a 应排在 b 后面(小顶堆)
bool cmpInt(const int& a, const int& b) {
return a > b; // 大的 a 往后放,堆顶是最小值
}
int main() {
// 第三个参数是函数指针类型(&cmpInt 可省略,函数名即指针)
priority_queue<int, vector<int>, decltype(&cmpInt)> pq(cmpInt);
pq.push(5);
pq.push(2);
pq.push(7);
// 出队:2 → 5 → 7
while (!pq.empty()) {
cout << pq.top() << " ";
pq.pop();
}
return 0;
}
// 输出:2 5 7
法一:优先队列(就用一个优先队列)超时
class MedianFinder {
private:
priority_queue<int>dl;
public:
MedianFinder() {
}
void addNum(int num) {
dl.push(num);
}
double findMedian() {
int l=dl.size();
priority_queue<int>temp;
temp=dl;
if(l%2!=0){//队列中有奇数个元素。
for(int i=0;i<l/2;i++){
temp.pop();
}
return temp.top();
}
else{
double y=0;
for(int i=0;i<(l/2)-1;i++){
temp.pop();
}
y=y+temp.top();
temp.pop();
y+=temp.top();
temp.pop();
return y/2;
}
}
};
/**
* Your MedianFinder object will be instantiated and called as such:
* MedianFinder* obj = new MedianFinder();
* obj->addNum(num);
* double param_2 = obj->findMedian();
*/
方法二:用两个堆
一个大根堆,一个小根堆
用一个大根堆:存放小于等于中位数,因为关键是存放最接近中位数的那个数,也就是这个队列中的最大数,为了快速获取这个最大值用大根堆
用一个小根堆:存放大于中位数的数,因为关键是存放最接近中位数的那个数,也就是这个队列中的最小数,为了快速获取这个最小值用小根堆\
class MedianFinder {
public:
priority_queue<int,vector<int>,greater<int>>que_Max;//存放大于中位数 小根堆
priority_queue<int,vector<int>,less<int>>que_Min;//存放小于等于中位数 大根堆
/*因为数组中元素可能是奇数个或偶数个
1.奇数个元素时 que_ Min中元素比que_Max元素多一个-->此时中位数是que_ Min.top()
2.偶数个元素时que_Min元素和que_Max元素一样多(que_ Min.top()+que_Max.top())/2.0
*/
MedianFinder() {}
void addNum(int num) {
if(que_Min.size()==0||(num<=que_Min.top())){//num小于中位数
que_Min.push(num);
if(que_Max.size()+1<que_Min.size()){//放入以后小于等于中位数的队列数字多了一个,弹出小于等于中位数的那个大根堆的顶(最大值)放入小根堆
que_Max.push(que_Min.top());
que_Min.pop();
}
}
else{
que_Max.push(num);
if(que_Max.size()>que_Min.size()){
que_Min.push(que_Max.top());
que_Max.pop();
}
}
}
double findMedian() {
if(que_Max.size()<que_Min.size()){
return que_Min.top();
}
else{
return (que_Max.top()+que_Min.top())/2.0;
}
}
};

浙公网安备 33010602011771号