LeetCode 20.有效的括号
视频链接:栈的拿手好戏!| LeetCode:20. 有效的括号_哔哩哔哩_bilibili
思路
括号匹配是使用栈解决的经典问题。首先我们要分析有几种不匹配的情况,第一种就是左边多出来括号了,第二种就是右边多出来括号了,第三种就是没有相应类型的括号可以匹配。当遇到左括号,就往栈里放相应的右括号,碰到相应的右括号,就从栈里消除右括号,这是一个小技巧,这可比碰到左括号就往栈里放左括号简单多了。如图所示:
代码实现
class Solution {
public:
bool isValid(string s) {
if(s.size() % 2 != 0) return false;
stack<char> st;
for(int i = 0;i < s.size();i++) {
if(s[i] == '(') st.push(')');
else if(s[i] == '{') st.push('}');
else if(s[i] == '[') st.push(']');
else if(st.empty() || st.top() != s[i]) return false;
else st.pop();
}
return st.empty();
}
};
·时间复杂度: O(n)
·空间复杂度: O(n)
LeetCode 1047.删除字符串中的所有相邻重复项
题目链接:1047. 删除字符串中的所有相邻重复项 - 力扣(LeetCode)
视频链接:栈的好戏还要继续!| LeetCode:1047. 删除字符串中的所有相邻重复项_哔哩哔哩_bilibili
思路
本题的栈里面放遍历过的元素,就像消消乐一样,如果栈里存放的元素和遍历的元素一样,就把栈里的元素消除,直到遍历完所有元素为止,最后栈里如果有元素就弹出,因为从栈里弹出的元素是倒的,所以在反转一下就能得出最终结果。如图所示:
代码实现
class Solution {
public:
string removeDuplicates(string S) {
stack<char> st;
for (char s : S) {
if (st.empty() || s != st.top()) {
st.push(s);
} else {
st.pop(); // s 与 st.top()相等的情况
}
}
string result = "";
while (!st.empty()) { // 将栈中元素放到result字符串汇总
result += st.top();
st.pop();
}
reverse (result.begin(), result.end()); // 此时字符串需要反转一下
return result;
}
};
·时间复杂度:O(n)
·空间复杂度:O(n)
也可以拿字符串直接作为栈,这样省去了栈还要转为字符串的操作。
代码实现(升级一下)
class Solution {
public:
string removeDuplicates(string S) {
string result;
for(char s : S) {
if(result.empty() || result.back() != s) {
result.push_back(s);
}
else {
result.pop_back();
}
}
return result;
}
};
·时间复杂度:O(n)
·空间复杂度:O(1),返回值不计空间复杂度
LeetCode 150.逆波兰表达式求值
题目链接:150. 逆波兰表达式求值 - 力扣(LeetCode)
视频链接:栈的最后表演! | LeetCode:150. 逆波兰表达式求值_哔哩哔哩_bilibili
思路
本题不仅仅是一道好题,也展现出计算机的思考方式。逆波兰表达式是用后序遍历的方式把二叉树序列化了,后缀表达式其实就是二叉树的后序遍历。过程如图所示:
代码实现
class Solution {
public:
int evalRPN(vector<string>& s) {
stack<int> st;
for(int i = 0;i < s.size();i++) {
if(s[i] == "+" || s[i] == "-" || s[i] == "*" || s[i] == "/") {
int num1 = st.top();
st.pop();
int num2 = st.top();
st.pop();
if (s[i] == "+") st.push(num2 + num1);
if (s[i] == "-") st.push(num2 - num1);
if (s[i] == "*") st.push(num2 * num1);
if (s[i] == "/") st.push(num2 / num1);
}
else {
st.push(stoi(s[i]));
}
}
int result = st.top();
st.pop();
return result;
}
};
·时间复杂度:O(n)
·空间复杂度:O(n)