开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情
栈
栈是一个很好用的STL容器,复杂度是logn的,有pop,pop,empty,push几种常用的操作,栈是遵循一个先进后出的原则,每次进去的元素都要先成为栈顶元素,然后循环下去。 栈也可以用数组模拟,也是很简单的,这里附上acwing的一个栈模拟的题目
828.模拟栈 用数组模拟栈,top代表栈顶,元素入栈就是++top,出栈就是top--,查询输出stk[top],判断栈是否空,就看top是不是等于0。当然直接用STL里面的stack也是可以的,但是复杂度有可能会高一点,其他的都一样。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
ll qmi(ll x,ll y,int mod){
ll res=1;
while(y){
if(y&1) res=res*x%mod;
y>>=1;
x=x*x%mod;
}
return res;
}
vector<int> alls;
const int N=100010;
int stk[N],top=0,m;
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>m;
while(m--){
string s;
int x;
cin>>s;
if(s=="push"){
cin>>x;
stk[++top]=x;
}
if(s=="query"){
cout<<stk[top]<<"\n";
}
if(s=="pop"){
top--;
}
if(s=="empty"){
if(top==0) cout<<"YES\n";
else cout<<"NO\n";
}
}
return 0;
}
单调栈
在了解了栈的基础上,我们可以看看的单调栈,单调栈,顾名思义,就是实现一个栈内元素单调递增或者单调递减的栈,可以在nlogn的时间复杂度内求解一些问题,接下来我们可以看一个例子 830.单调栈,这题是要求输出每个数左边第一个比它小的数的值,这题显然我们是可以暴力的,但是肯定得不到满分,只能拿到部分分,因为暴力枚举的话,时间复杂度是的,那这题我们可以考虑维护一个单调递增的栈,如果输入的元素比栈顶元素大,那么我们就输出栈顶元素,并且把当前元素入栈,如果输入的元素比栈顶元素小,那么我们就把栈内所有的比当前元素大的值全部弹出,如果栈还是非空的,那么就输出栈顶元素,并且把当前数入栈,否则就输出-1.
数组模拟栈的代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
ll qmi(ll x,ll y,int mod){
ll res=1;
while(y){
if(y&1) res=res*x%mod;
y>>=1;
x=x*x%mod;
}
return res;
}
const int N=100010;
int stk[N],top=0;
int a[N],n;
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
while(x<=stk[top] && top) top--;
if(top) cout<<stk[top]<<" ";
else cout<<"-1 ";
stk[++top]=x;
}
return 0;
}
直接用STL的栈的代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
stack<int> stk;
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
ll qmi(ll x,ll y,int mod){
ll res=1;
while(y){
if(y&1) res=res*x%mod;
y>>=1;
x=x*x%mod;
}
return res;
}
const int N=100010;
int a[N],n;
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
int x;
cin>>x;
while(!stk.empty()){
int t=stk.top();
if(t>=x) stk.pop();
else break;
}
if(stk.empty()) cout<<"-1 ";
else cout<<stk.top()<<" ";
stk.push(x);
}
return 0;
}
接下来看看洛谷一题
【模板】单调栈
题目背景
模板题,无背景。
2019.12.12 更新数据,放宽时限,现在不再卡常了。
题目描述
给出项数为 的整数数列 。
定义函数 代表数列中第 个元素之后第一个大于 的元素的下标,即 。若不存在,则 。
试求出 。
输入格式
第一行一个正整数 。
第二行 个正整数 。
输出格式
一行 个整数 的值。
样例 #1
样例输入 #1
5
1 4 2 3 5
样例输出 #1
2 5 4 5 0
提示
【数据规模与约定】
对于 的数据,;
对于 的数据, ;
对于 的数据,,。
分析
洛谷这个模板题,其实就是要把序列给reverse一下,然后维护一个单调递减的栈即可
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
//stack<int> stk;
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
ll qmi(ll x,ll y,int mod){
ll res=1;
while(y){
if(y&1) res=res*x%mod;
y>>=1;
x=x*x%mod;
}
return res;
}
const int N=3000010;
int a[N],n,stk[N],top=0,xb[N];
ll dp[N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
reverse(a+1,a+n+1);
for(int i=1;i<=n;i++){
while(a[stk[top]]<=a[i] && top) top--;
if(!top) xb[i]=0;
else xb[i]=stk[top];
stk[++top]=i;
}
for(int i=n;i>=1;i--){
if(xb[i]) xb[i]=n+1-xb[i];
cout<<xb[i]<<" ";
}
return 0;
}
希望能帮助到大家,QAQ!