最小栈
思路
用两个栈实现,一个栈正常插入和删除,另一个栈记录当前最小元素,第一个栈删除的时候,如果和最小的栈顶元素相等,最小的栈也删除元素
class MinStack {
public:
MinStack() {
}
void push(int val) {
st.push(val);
if (min.empty() || min.top() >= val)
{
min.push(val);
}
}
void pop() {
if (min.top() == st.top())
{
min.pop();
}
st.pop();
}
int top() {
return st.top();
}
int getMin() {
return min.top();
}
private:
stack<int> st;
stack<int> min;
};
/**
* 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();
*/
自定义类型不需要构造里初始化,因为对于自定义类型会自动调用它的构造
栈的压入弹出
思路
用两个下标记录压栈和弹栈顺序表,压栈时压栈下标增加,弹栈时弹栈下标增加,如果栈顶元素和弹栈表相等就弹出,栈为空且弹栈下标等于它的长度,说明全部匹配了
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pushV int整型vector
* @param popV int整型vector
* @return bool布尔型
*/
bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
// write code here
stack<int> v;
int i = 0;
int j = 0;
while (i < popV.size()) {
v.push(pushV[i]);
while (!v.empty() && v.top() == popV.at(j)) {
v.pop();
j++;
if (v.empty() && j == popV.size()) {
return true;
}
}
i++;
}
return false;
}
};
逆波兰表达式
思路
逆波兰表达式是已经排好计算顺序的表达式,遇到计算符就取最近的两个操作数计算,得到的结果加入到里面。这刚好符合栈后进先出的特点,先取出的是右操作数,后取的是左操作数
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();
int ret = 0;
switch(str[0])
{
case '+':
ret = left + right;
st.push(ret);
break;
case '-':
ret = left - right;
st.push(ret);
break;
case '*':
ret = left * right;
st.push(ret);
break;
case '/':
ret = left / right;
st.push(ret);
break;
}
}else
{
st.push(stoi(str));
}
}
return st.top();
}
};
后缀转中缀
后缀表达式就是正常的计算表达式,根据后缀转中缀,就可以完成对表达式的求值过程
遇到数字直接输出
遇到运算符判断
1.如果这个运算符比栈顶的运算符优先级高,进栈
2.如果这个运算符比栈顶的运算符优先级低,出栈
遇到括号
1.默认左括号优先级最低,左括号进栈
2.遇到右括号,将栈内元素不停弹出,直到匹配到左括号,将左右括号丢弃
遍历结束,将栈中所有内容弹出并输出