刷前学习:
优先队列(priority_queue)用法:
-
相同处:
-
同queue,都需要使用
#include<queue>
; -
和队列的基本操作相同
1、top访问队头元素 2、pop弹出队头元素 3、empty队列是否为空 4、push插入元素到队尾(并排序) 5、size返回队列内元素的个数 6、emplace原地构造一个元素并插入队列 7、swap内容交换
-
-
不同处:
-
”披着队列外衣“的堆,添加了内部排序
-
优先队列(priority_queue)定义:
priority_queue<Type,Container,Functional
Type是数据类型,Container是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用list。默认的类型是vector),Functional就是比较方式,默认是大顶堆
代码:
//升序队列
priority_queue<int,vector<int>,greater<int>>q;
//降序队列
priority_queue<int,vector<int>,less<int>>q;
//greater和less是std的两个仿函数(就是使用一个类看上去是一个函数。其实就是在类中实现了一个operator(),这个类就有了类似函数的行为,就是模仿函数了)
基本用法代码:
#include<iostream>
#include<queue>
using namespace std;
int main(){
//默认就是大顶堆
priority_queue<int>a;//相当于priority_queue<int,vector<int>,less<int> >a;
//小顶堆 (升序)
priority_queue<int,vector<int>,greater<int> >c;
// 大顶堆
priority_queue<string>b;
for(int i=4;i>=0;i--){
a.push(i);
c.push(i);
}
while(!a.empty()){
cout << a.top() << ' ';
a.pop();
}
cout << endl;
while(!c.empty()){
cout << c.top() << ' ';
c.pop();
}
cout << endl;
b.push("abc");
b.push("abcd");
b.push("bcd");
while(!b.empty()){
cout << b.top() << ' ';
b.pop();
}
cout << endl;
return 0;
}
输出:
4 3 2 1 0
0 1 2 3 4
cbd abcd abc
pair的比较,先比较第一个元素,第一个相等比较第二个
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
int main(){
priority_queue<pair<int,int> >a;
pair<int,int>b(2,5);
pair<int,int>c(1,2);
pair<int,int>d(1,3);
a.push(b);
a.push(c);
a.push(d);
while(!a.empty()){
cout << a.top().first << ' ' <<a.top().second <<'\n';
a.pop();
}
cout<< endl;
return 0;
}
输出:
2 5
1 3
1 2
自定义类型
#include<iostream>
#include<queue>
using namespace std;
struct tmp1{
int x;
tmp1(int a){
x=a;
}
bool operator<(const tmp1& a)const{
return x<a.x;
}
};
struct tmp2{
bool operator()(tmp1 a,tmp1 b){
return a.x<b.x;
}
};
int main(){
tmp1 a(1);
tmp1 b(2);
tmp1 c(3);
priority_queue<tmp1> d;
d.push(a);
d.push(b);
d.push(c);
while(!d.empty()){
cout << d.top().x << '\n';
d.pop();
}
cout << endl;
priority_queue<tmp1,vector<tmp1>,tmp2> f;
f.push(a);
f.push(b);
f.push(c);
while(!f.empty()){
cout << f.top().x << '\n';
f.pop();
}
cout << endl;
return 0;
}
开刷:
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
-
1 <= nums.length <= 105
-
k 的取值范围是 [1, 数组中不相同的元素的个数]
-
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
(代码时间复杂度为n*logk):
class Solution {
public:
class mycomparison{
public:
bool operator()(const pair<int,int>& lhs,const pair<int,int>& rhs){
return lhs.second>rhs.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int>map;
for(int i=0;i<nums.size();i++){
map[nums[i]]++;
}
priority_queue<pair<int,int>,vector<pair<int,int>>,mycomparison> pri_que;
for(unordered_map<int,int>::iterator it=map.begin();it!=map.end();it++){
pri_que.push(*it);
if(pri_que.size()>k){
pri_que.pop();
}
}
vector<int>result(k);
for(int i=k-1;i>=0;i--){
result[i]=pri_que.top().first;
pri_que.pop();
}
return result;
}
};