题意
需要模拟一个栈结构,支持 4 种操作:
push x:将数字 x 压入栈;
pop:弹出栈顶元素;
top:查询并输出栈顶元素;
get_min:O (1) 时间复杂度查询并输出栈内最小值。
特殊规则
如果栈为空时执行 pop / top / get_min,属于非法操作,输出 error。
难点要求
普通栈每次查最小值需要遍历全部元素,时间复杂度 O (n),不满足要求;
必须设计辅助结构,保证获取最小值操作为 O (1)。
解题核心思路:双栈法
主栈:存放所有入栈数字,负责基础入栈、出栈、取栈顶;
最小值辅助栈:只存阶段性最小值,栈顶永远是当前全局最小值。
入栈:新数字 ≤ 辅助栈顶时,同步压入辅助栈;
出栈:弹出元素等于辅助栈顶时,辅助栈同步弹出;
所有操作均为 O (1)。
二、完整 AC 代码
cpp
运行
#include <bits/stdc++.h>
using namespace std;
stack<int> s,m;
int main(){
int n,x;string o;
cin>>n;
while(n--&&cin>>o){
if(o=="push"){
cin>>x;s.push(x);
if(m.empty()||x<=m.top())m.push(x);
}else if(s.empty())cout<<"error\n";
else if(o=="pop"){if(m.top()s.top())m.pop();s.pop();}
else cout<<(o"top"?s.top():m.top())<<'\n';
}
}
三、逐行代码解析
#include <bits/stdc++.h>
万能头文件,一次性包含 stack、iostream、string 等竞赛常用库,无需分开导入。
using namespace std;
启用标准命名空间,省略 stdcin、stdstack 等前缀。
stack<int> s,m;
定义两个栈:
s:主栈,存储全部数据;
m:最小值辅助栈,栈顶保存当前栈最小值。
int main(){
程序入口函数。
int n,x;string o;
变量定义:
n:操作总次数;
x:push 传入的数值;
o:保存操作指令字符串。
cin>>n;
读取第一行输入,获取操作总条数。
while(n--&&cin>>o){
循环执行 n 次操作:
n--:每轮操作次数减一;
cin>>o:读取当前操作指令。
if(o=="push"){
分支:当前操作为入栈。
cin>>x;s.push(x);
读取要插入的数字 x,并将 x 压入主栈 s。
if(m.empty()||x<=m.top())m.push(x);
维护最小栈:
最小栈为空,或新数字小于等于栈顶,说明出现更小 / 相等最小值,同步压入辅助栈 m。
}else if(s.empty())cout<<"error\n";
非 push 操作,先判断栈是否为空:空栈执行 pop/top/get_min 非法,输出 error。
else if(o=="pop"){if(m.top()s.top())m.pop();s.pop();}
操作是出栈且栈非空:
如果主栈弹出的元素等于辅助栈顶,代表当前最小值被移除,辅助栈同步出栈;最后主栈弹出元素。
else cout<<(o"top"?s.top():m.top())<<'\n';
剩余操作只有 top 和 get_min,三目运算符简化判断:
指令为 top:输出主栈栈顶;
指令为 get_min:输出最小栈栈顶;
'\n' 换行,比 endl 效率更高。
后续括号依次闭合分支、循环、主函数,程序结束。
四、样例演示
输入:
plaintext
6
top
push 4
push 5
top
pop
get_min
执行过程:
top:栈空 → error
push 4:主栈 [4],最小栈 [4]
push 5:主栈 [4,5],5>4,最小栈不变
top:输出栈顶 5
pop:弹出 5,与最小栈顶 4 不相等,最小栈不变,主栈 [4]
get_min:输出最小栈顶 4