堆栈、队列、单调栈、单调队列

Stack和Queue——栈和队列

  • 栈的定义:栈是限定仅在表头进行插入和删除操作的线性表(先进后出)
  • 队列的定义:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。(先进先出)
    stack常用函数:
  • push()——向栈顶压入元素
  • pop()——弹出栈顶元素
  • top()——访问栈顶元素
    queue常用函数:
  • front()——访问队首元素
  • back()——访问队尾元素
  • push()——向队尾插入元素
  • pop()——弹出队首元素

出栈顺序

题目描述:
有n个人,按照1,2,3...n的顺序依次进栈,判读能否以题目所给序列出栈。(n <= 100000)
eg:

  • 4 3 2 1
  • 1 2 3 4
  • 1 3 2 4
  • 1 4 2 3
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int a[N];
int n;
stack<int> stk;
int main() {
ios;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int j = 1;
for (int i = 1; i <= n; i++) {
stk.push(i);
while (!stk.empty() && a[j] == stk.top()) {
stk.pop();
j++;
}
}
if (!stk.empty()) cout << "No";
else cout << "Yes";
return 0;
}

栈和排序

思路:
如果栈顶元素比后面没入栈的元素都大,那么它就应该出栈

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int a[N], maxn[N]; //maxn数组预处理后缀最大值
int n;
stack<int> stk;
int main() {
ios;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
//预处理
for (int i = n; i >= 1; i--) {
maxn[i] = max(a[i], maxn[i + 1]);
}
for (int i = 1; i <= n; i++) {
stk.push(a[i]);
while (!stk.empty() && stk.top() > maxn[i + 1]) { //还没进栈的元素是否没有比栈顶元素大的
printf("%d ", stk.top());
stk.pop();
}
}
//如果栈内还有元素,就直接输出
while (!stk.empty()) {
printf("%d ", stk.top());
stk.pop();
}
return 0;
}

好串

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long LL;
string s;
stack<int> stk;
int main() {
ios;
cin >> s;
for (int i = 0; i < s.size(); i++) {
if (s[i] == 'a') {
stk.push('a');
} else {
if (stk.empty()) {
cout << "Bad" << endl;
return 0;
} else {
stk.pop();
}
}
}
if (stk.empty()) cout << "Good";
else cout << "Bad";
return 0;
}

合并果子

思路:
思考易得,每次选择当前的果子数最少的两堆进行合并,花费的体力最少
维护两个队列
q1表示还没有合并的果子从小到大的序列
q2表示已经合并的果子的序列(自然从小到大,因为越合并果子数越大)
每次判断两个队列的队首元素大小小的出列合并完放入q2

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int a[N];
int n;
queue<int> q1, q2;
int main() {
ios;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++) {
q1.push(a[i]);
}
int ans = 0;
for (int i = 1; i < n; i++) {
int x[3];
for (int j = 1; j <= 2; j++) {
if (q2.empty() || (!q1.empty() && q1.front() < q2.front())) { //注意取q1的条件,q2为空,或者q1不为空,且q1队首小于q2队首
x[j] = q1.front();
q1.pop();
} else {
x[j] = q2.front();
q2.pop();
}
}
ans += x[1] + x[2];
q2.push(x[1] + x[2]);
}
cout << ans << endl;
return 0;
}

优先队列写法:

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define bug(x) cout<<#x<<"=="<<x<<endl;
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n;
int a[N];
priority_queue<int, vector<int>, greater<int> >q;
int main() {
ios;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
q.push(a[i]);
}
LL ans = 0;
for (int i = 1; i < n; i++) {
int tmp1 = q.top();
q.pop();
int tmp2 = q.top();
q.pop();
ans += tmp1 + tmp2;
q.push(tmp1 + tmp2);
}
cout << ans << endl;
return 0;
}

滑动窗口(deque)

题目描述:
给定一个长度为n的数列,求长度为k的定长连续子区间{a1,a2,a3,...ak1,ak},{a2,a3,...ak,ak+1}......中每个区间的最大值和最小值。

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, k;
int a[N];
deque<int> maxn, minn;
int main() {
ios;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
if (!minn.empty() && i - minn.front() >= k) minn.pop_front();
while (!minn.empty() && a[i] <= a[minn.back()]) {
minn.pop_back();
}
minn.push_back(i);
if (i >= k) cout << a[minn.front()];
}
cout << endl;
for (int i = 1; i <= n; i++) {
if (!maxn.empty() && i - maxn.front() >= k) maxn.pop_front();
while (!maxn.empty() && a[i] >= a[maxn.back()]) {
maxn.pop_back();
}
maxn.push_back(i);
if (i >= k) cout << a[maxn.front()];
}
return 0;
}

Look up

Largest Rectangle in a Histogram

posted @   csai_H  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示