1. 最小栈
155. 最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop()
删除堆栈顶部的元素。 int top() 获取堆栈顶部的元素。 int getMin() 获取堆栈中的最小元素。示例 1:
输入: [“MinStack”,“push”,“push”,“push”,“getMin”,“pop”,“top”,“getMin”]
[[],[-2],[0],[-3],[],[],[],[]]输出: [null,null,null,null,-3,null,0,-2]
解释: MinStack minStack = new MinStack(); minStack.push(-2);
minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3.
minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin();
–> 返回 -2.
思路: 我们可以设定两个栈,一个存放val元素,另一个存放val元素中的最值。
在val值入栈时我们需要注意的是,当_minstr 栈为空时需要将val入栈。当_minstr栈顶的值大于要插入的val时入栈。
在删除栈中的值时需要注意的是,_minstr中最小值出现重复的值,也需要删除。
#include<stack>
class MinStack {
public:
MinStack() {
}
void push(int val) {
_str.push(val);
if(_minstr.empty() || val <= _minstr.top())
{
_minstr.push(val);
}
}
void pop() {
if(_str.top()== _minstr.top())
{
_minstr.pop();
}
_str.pop();
}
int top() {
return _str.top();
}
int getMin() {
return _minstr.top();
}
stack<int> _str;
stack<int> _minstr;
};
2. 栈的压入、弹出序列
JZ31 栈的压入、弹出序列
描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列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 的所有数字均不相同
思路:设置双指针,第一指针指向入栈序列的开始位置,第二个指向出栈序列中的开始位置。设置一个类型为int的栈对象,遍历入栈序列,将pushi指向的位置入栈, 再判断栈顶元素是等于出栈序列popi指向的数据,若是等于便popi自增并删除栈顶元素。
如图:
#include <stack>
class Solution {
public:
bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
int pushi = 0;
int popi = 0;
stack<int> str;
while(pushi <pushV.size())
{
str.push(pushV[pushi++]);
while(!str.empty() && str.top() == popV[popi])
{
++popi;
str.pop();
}
}
return str.empty();
}
};
3.逆波兰表达式求值
150. 逆波兰表达式求值
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
请你计算该表达式。返回一个表示表达式值的整数。
注意:
有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个整数之间的除法总是
向零截断 。 表达式中不含除零运算。 输入是一个根据逆波兰表示法表示的算术表达式。 答案及所有中间计算结果可以用 32 位 整数表示。示例 1:
输入:tokens = [“2”,“1”,“+”,“3”,“*”] 输出:9 解释:该算式转化为常见的中缀算术表达式为:((2 + 1) *
3) = 9 示例 2:输入:tokens = [“4”,“13”,“5”,“/”,“+”] 输出:6 解释:该算式转化为常见的中缀算术表达式为:(4 + (13
/ 5)) = 6 示例 3:输入:tokens = [“10”,“6”,“9”,“3”,“+”,“-11”,““,”/“,””,“17”,“+”,“5”,“+”]
输出:22 解释:该算式转化为常见的中缀算术表达式为: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
思路:逆波兰表达式就是中缀表达式。我们这里需要建立一个栈 ,将题目中会出现的符号放入set集合中。遍历vector中的数据 ,判断str中的数据是否为符号,若不是就将数字入栈,若是取出栈顶的数据为右运算数,再取一个作为左运算数,不要忘记对栈顶元素进行删除。利用switch判断vector首元素是否存在并符合case的情况。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> s;
set<string> s1 = {"+","-","*","/"};
for(auto& str : tokens)
{
if(s1.find(str) != s1.end())
{
int right = s.top();
s.pop();
int left = s.top();
s.pop();
switch(str[0])
{
case '+':
s.push(left+right);
break;
case '-':
s.push(left-right);
break;
case '*' :
s.push(left*right);
break;
case '/' :
s.push(leftright);
break;
}
}
else
{
s.push(stoi(str));
}
}
return s.top();
}
};