栈
一、基础知识
1、栈是一个先入后出的有序列表
2、栈中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端(变化的一端),称为栈顶(Top);另一端为固定的一端,称为栈底(Bottom)。
3、根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除。
二、题解
1、20. 有效的括号
栈的核心————先进后出,后进先出
1、左括号入栈
2、右括号:三种情况
1)栈为空,false
2)与栈顶元素不匹配,false
3)与栈顶元素匹配,true,并将栈顶元素出栈
class Solution {
public:
bool isValid(string s) {
stack<char>str;
char t;
for(char c:s){
if(c == '(' || c == '[' || c == '{') str.push(c);
else{
if(str.empty()) return false;
t = str.top();str.pop();
if (c == ')' && t != '(') return false;
if (c == ']' && t != '[') return false;
if (c == '}' && t != '{') return false;
}
}
return str.empty();
}
};
2、150. 逆波兰表达式求值
前序表达式、中序表达式、后序表达式
- 中序表达式:
我们日常使用的表达式,从左往右阅读,结构清晰,但是需要括号改变优先级,对计算机不友好。
eg: (1+4)*3+10/5- 前序表达式(波兰表示法Polish notation,或波兰记法)
中序表达式: (1+4)*3+10/5
前序表达式: + * + 1 4 3 / 10 5
其特点是操作符置于操作数前面,从右往左阅读,从右边第一个字符开始判断,如果当前字符是数字则继续扫描,如果当前字符是运算符,将运算符右边最近的两个数字做运算,结果作为新的字符记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。- 后序表达式(逆波兰表示法(Reverse Polish notation,RPN,或逆波兰记法)
中序表达式: (1+4)*3+10/5
后序表达式: 1 4 + 3 * 10 5 / +
其求值和前序表达式十分相似,后序表达式是从左至右扫描表达式,从左边第一个字符开始判断,如果的那个字符是数字继续扫描,如果是运算符,将运算符左边最近的两个数字做运算,结果作为新的字符记录下来。一直扫描到表达式的最右端时,最后运算的值也就是表达式的值。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for (auto &ch: tokens) {
if (ch == "+" || ch == "-" || ch =="*" || ch == "/") {
int b = st.top();st.pop();
int a = st.top();st.pop();
if ("+" == ch) {
st.push(a + b);
}
if ("-" == ch) {
st.push(a - b);
}
if ("*" == ch) {
st.push(a * b);
}
if ("/" == ch) {
st.push(a / b);
}
}
else {
st.push(stoi(ch));
}
}
return st.top();
}
};
3、224. 基本计算器
class Solution {
public:
int calculate(string s) {
stack<int> sign; //栈顶记录当前符号
sign.push(1); //默认为正
int res = 0, num = 0, op = 1;
for (char ch : s)
{ //空格可以不管,直接忽略
if (ch >= '0' && ch <= '9') //取出完整数值
{
num = num * 10 + (ch - '0');
continue;
}
res += op * num; //计算一个运算符
num = 0; //数值清空
if (ch == '+') op = sign.top();
else if (ch == '-') op = -sign.top();
else if (ch == '(') sign.push(op); //进入左括号,把左括号之前的符号置于栈顶
else if (ch == ')') sign.pop(); //退出括号,弹出栈顶符号
}
res += op * num; //计算最后一个数
return res;
}
};