题目
题目描述
给定一个数列,初始为空,请支持下面三种操作:
给定一个整数 x,请将 x 加入到数列中。
输出数列中最小的数。
删除数列中最小的数(如果有多个数最小,只删除 1 个)。
输入格式
第一行是一个整数,表示操作的次数 n。
接下来 n 行,每行表示一次操作。每行首先有一个整数 op 表示操作类型。
若 op = 1,则后面有一个整数 x,表示要将 x 加入数列。
若 op = 2,则表示要求输出数列中的最小数。
若 op = 3,则表示删除数列中的最小数。如果有多个数最小,只删除 1 个。
输出格式
对于每个操作 2,输出一行一个整数表示答案
题解
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
int main(){
priority_queue<int,vector<int>,greater<int> > q;
int n;
scanf("%d",&n);
for(int i = 0;i < n;i++){
int op,x;
scanf("%d",&op);
switch(op){
case 1:
scanf("%d",&x);
q.push(x);
break;
case 2:
printf("%d\n",q.top());
break;
case 3:
q.pop();
break;
}
}
return 0;
}
这道题如果使用sort
函数会超时,这个可以通过复杂度来分析。
sort
函数使用的排序方法为快速排序法(简称快排),时间复杂度为
O
(
n
l
o
g
2
n
)
O(nlog_2n)
O(nlog2n)。
但是在本题,如果使用sort
函数,那么至少需要在每一次插入新元素时调用一次,因此在本题的时间复杂度为
O
(
n
2
l
o
g
2
n
)
O(n^2log_2n)
O(n2log2n)。
而使用堆结构(即优先队列),那么本题的时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)——一次插入操作的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)。
第七行
priority_queue<int,vector<int>,greater<int> > q;
这一句是优先队列对象的定义。
priority_queue
类模板中有三个参数:int
、vector<int>
、greater<int>
。
- 第一个参数
int
:指明了该优先队列对象中元素的类型 - 第二个参数
vector<int>
:指明了该优先队列所使用的存储容器,一般使用vector
,也可以使用queue
- 第三个参数
greater<int>
:指明了该优先队列为小顶堆类型。(greater
对应小顶堆,less
对应大顶堆)
尖括号中的这三个参数指明了该优先队列具体的存储元素的类型、存储结构和大小堆类型。
对于堆结构,可参考资料:
原创不易,感谢支持。