本文包含的Leetcode题目
- 有效的括号(Leetcode20)
- 逆波兰表达式求值(Leetcode150)
- 删除字符串中所有相邻重复项(Leetcode1047)
栈(stack)
栈是一种先进后出的数据结构,在C++ STL默认使用deque(双向队列)进行实现(stack不算容器,算是一种容器适配器),STL中栈的使用方法如下:
stack<T> st; //构造一个栈结构
st.pop(); //弹出栈顶元素,无返回值
st.top(); //返回栈顶元素
st.push(a); //将a入栈
st.size(); //返回栈中元素的个数
st.empty(); //判断栈是否为空,返回bool类型
注意STL中stack不提供迭代器,无法进行遍历等操作。
栈数据结构的使用场景
- 计算机系统中很多情况都会使用stack来存放参数(如递归是系统进行压栈)
- “匹配”问题(符号匹配)
- 栈结构有能力将数据反置(如二叉树后续遍历的迭代写法)
Leetcode 20:有效的括号
“匹配”类问题优先考虑栈结构,本题要考虑三种可能无效的情况:
1.右括号和左括号对不上(数据和栈顶不等)
2.右括号比左括号多(栈空还有数据)
3.左括号比右括号多(数据空还有栈)
class Solution {
public:
bool isValid(string s) {
stack<char> s0;
for (char c : s) {
if (c == '(') s0.push(')');
else if (c == '[') s0.push(']');
else if (c == '{') s0.push('}');
else if (s0.empty() || s0.top() != c) return false;
else s0.pop();
}
return s0.empty();
}
};
Leetcode150:逆波兰表达式求值
同样是关于匹配问题,同样使用栈结构,遇到数字压栈,遇到运算符进行计算,将结果压栈。
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for (int i = 0; i < tokens.size(); i++) {
if (tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/") {
int num1 = st.top();
st.pop();
int num2 = st.top();
st.pop();
if (tokens[i] == "+") st.push(num2 + num1);
if (tokens[i] == "-") st.push(num2 - num1);
if (tokens[i] == "*") st.push(num2 * num1);
if (tokens[i] == "/") st.push(num2 / num1);
} else {
st.push(stoi(tokens[i]));
}
}
return st.top();
}
};
Tips
C++中 string->int: stoi(); int->string: to_string()
Leetcode1047:删除字符串中的所有相邻重复项
本质上还是字符的两两匹配问题
class Solution {
public:
string removeDuplicates(string S) {
stack<char> st;
string res;
for (char c : S) {
if (st.empty() || st.top() != c) st.push(c);
else st.pop();
}
while (!st.empty()) {
res += st.top();
st.pop();
}
reverse(res.begin(), res.end());
return res;
}
};