栈
最小栈
题目链接:https://leetcode.cn/problems/min-stack/description/
题目要求:
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
1)MinStack() 初始化堆栈对象。
2)void push(int val) 将元素val推入堆栈。
3)void pop() 删除堆栈顶部的元素。
4)int top() 获取堆栈顶部的元素。
5)int getMin() 获取堆栈中的最小元素。
解题思路 :分别实现两个栈st和minst,其中st栈正常进行压栈和出栈操作,每次记录st栈的值。当push数据到st栈,如果该值比minst栈的值小,就push到minst栈中。当pop数据时,如果pop的数据跟minst栈顶数据相等,则同时对minst进行出栈操作,这样就能保证st栈中的最小值始终时minst的栈顶元素。
图示 :

代码实现:
cpp
class MinStack {
public:
MinStack() {
}
void push(int val) {
st.push(val);
if(minst.empty()||val<=minst.top())
{
minst.push(val);
}
}
void pop() {
if(st.top()==minst.top())
{
minst.pop();
}
st.pop();
}
int top() {
return st.top();
}
int getMin() {
return minst.top();
}
private:
stack<int> st;
stack<int> minst;
};
栈的压入,弹出序列
题目要求:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
- 0<=pushV.length == popV.length <=1000
- -1000<=pushV[i]<=1000
- pushV 的所有数字均不相同
解题思路 :
模拟栈的压入和弹出,建立一个栈,给两个下标变量pushVi指向第一序列的第一个,popVi指向第二个序列的第一个。然后对第一个序列的数据进行压栈,直到栈顶的数据和第二序列的数据相同,开始出栈,每次出栈都验证是否相同,不同,则继续入栈,相同,则继续出栈。
图示 :

代码实现:
cpp
bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
// write code here
stack<int> st;
int pushVi=0;
int popVi=0;
while(pushVi<pushV.size())
{
st.push(pushV[pushVi++]);
while(!st.empty()&&st.top()==popV[popVi])//只要栈不为空并且栈顶元素等于要出的元素,则弹出栈。
{
st.pop();
popVi++;
}
}
return st.empty();
}
逆波兰表达式求值
题目链接 :https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/
题目详情:
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数 。
注意:
1.有效的算符为 '+'、'-'、'*' 和 '/' 。
2.每个操作数(运算对象)都可以是一个整数或者另一个表达式。
3.两个整数之间的除法总是 向零截断 。
4.表达式中不含除零运算。
5.输入是一个根据逆波兰表示法表示的算术表达式。
6.答案及所有中间计算结果可以用 32 位 整数表示
解题思路:
首先我们要了解中缀表达式 和后缀表达式 :
中缀表达式就是平常我们写代码写的那些表达式,如2*2+1;但涉及到操作符的优先级问题,中缀表达式不方便我们计算机进行计算。以此,我们计算机采用的运算表达式是后缀表达式,这里讲两个问题:1.中缀表达式如何转化成后缀表达式;2.后缀表达式的运算。
1.中缀表达式如何转化成后缀表达式
后缀表达式的概念:
操作数顺序不变,操作符根据优先级进行重新排序
转化过程:对中缀表达式进行转化
首先建立建立一个栈,然后:
1.如果是操作数,则直接输出
2.如果是操作符,也有两种情况
1)如果栈为空或者当前操作数的优先级高于栈顶操作数,则入栈
2)如果栈不为空且当前操作数的优先级低于和等于栈顶操作数,则出栈顶操作数
同时要考虑括号等特殊情况,可以使用递归等方法解决,这里做了解就行
2.后缀表达式的运算
运算过程:对后缀表达式进行运算
同样的先建立一个栈,不同的是对操作数才入栈和出栈:
1.如果是操作数,则入栈
2.如果遇到操作符,取栈顶两个元素进行出栈进行运算,再将运算后的结果入栈。
那么我们这道题就是后缀表达式的运算
代码实现:
cpp
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for(auto& str:tokens)
{
if(str=="+"||str=="-"||str=="*"||str=="/")
{
int right=st.top();
st.pop();
int left=st.top();
st.pop();
switch(str[0])
{
case '+':
st.push(left+right);
break;
case '-':
st.push(left-right);
break;
case '*':
st.push(left*right);
break;
case '/':
st.push(left/right);
break;
}
}
else
{
st.push(stoi(str));
}
}
return st.top();
}
};