前言:
本次好题分析我们将主要对我们在STL库中所学习的stack进行锻炼,主要涉及以下题目:
《最小栈》《栈的弹出压入序列》《逆波兰表达式求值》
题目一:《最小栈》
class MinStack {
public:
MinStack() {
}
void push(int val) {
s1.push(val);
if(ans_stack.empty() || ans_stack.top() >= val)
{
ans_stack.push(val);
}
}
void pop() {
if(s1.top() == ans_stack.top()) ans_stack.pop();
s1.pop();
}
int top() {
return s1.top();
}
int getMin() {
return ans_stack.top();
}
stack<int> s1;
stack<int> ans_stack;
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(val);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
对于该题目,重点是我们需要在常熟时间获得栈的最小值,所以我们是绝对不能去遍历这个栈的。
对此我们可以调用新学习的STL的stack,来创建两个栈。
我们定义一个栈为s1,一个栈为ans_stack,ans_stack用来接收 “嫌疑”值
假设我们按照 4 2 1 3的顺序来push。
S1就按照普通的push,而ans_stack则判断,如果该栈的 栈顶元素 > push进来的值,那么就不进栈,如果栈顶元素 <= push进来的值就进栈。
如下:
通过上述即可找到最小值,但是对于pop我们也要额外注意!!!
题目二:《栈的弹出压入序列》
栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)
class Solution
{
public:
bool IsPopOrder(vector<int>& pushV, vector<int>& popV)
{
stack<int> st;
int pos = 0;
for(int i = 0; i < pushV.size(); ++i)
{
st.push(pushV[i]);
while(!st.empty() && st.top() == popV[pos])
{
st.pop();
pos++;
}
}
return st.empty();
}
};
如果有参加过数据结构的考试,那么这道题再熟悉不过,简单来说就是假如我要按照12345的方式入栈,那么该怎么出栈才能让栈为空,但是这道题考察的不是怎么实现,而是判断。
题目三:《逆波兰表达式求值》
class Solution {
public:
int evalRPN(vector<string>& tokens) {
set<string> s{"+", "-", "*", "/"};
stack<int> st;
int sum = 0;
for(auto& str : tokens)
{
// 操作数入栈,操作符运算
if(s.find(str) != s.end())
{
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();
}
};
这道题也是数据结构的考试里面的一道题型,相信学过的或多或少都见过,我在这里也不做过多的赘述。这道题我们需要利用一个我们之前未学过的set容器,来收集符号。
具体的方法就是————“操作数入栈,操作符运算”