关于验证栈序列O(n)做法的常数优化
一般算法(模拟)
模拟栈的压入与弹出,理论上每个元素最多要经过一次入栈一次出栈,大概在
改进算法
输入一个
第二行
第一种情况:
第
那我们来思考是不是只用记录
答案是肯定的,因为出栈只需要不断地判断栈顶,所以我们只需要维护栈顶
但是如果
第二种情况:
即第
特殊情况:
比如
出现
按照上述算法会发现,当判断
显然,应该先让
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[100005];
bool check(int n){
bool s[100005];//记录i是否已经合法出栈
stack<int>q;//储存当前栈顶元素
int maxx=0;//记录最大值
for(int i=1;i<=n;i++){
if(a[i]>maxx){//最大值一定可以入栈并出栈
maxx=a[i];
//特别的,a[i]==1时不能记录1-1即0
if(!s[a[i]-1]&&a[i]>1)q.push(a[i]-1);//记录栈顶
s[a[i]]=1;
}
else{
if(q.empty()){//栈空也可以正常弹出
s[a[i]]=1;
if(!s[a[i]-1]&&a[i]>1)q.push(a[i]-1);
continue;
}
if(q.top()==a[i]){
q.pop();
s[a[i]]=1;
if(!s[a[i]-1]&&a[i]>1)q.push(a[i]-1);
continue;
}
return 0;
}
}
return 1;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
cout<<check(n);
return 0;
}
感谢各位dalao的观看,代码可以正常过P4387验证栈序列,如果有不对之处或可改进之处欢迎反馈!