文章目录
栈在算法中的应用
(Stack)是一种遵循后进先出(Last In First Out, LIFO)原则的数据结构,它在解决特定类型的算法问题时非常有用。以下是一些典型的算法问题,其中栈的使用尤为适合:
括号匹配问题
检查给定的表达式中的括号(包括圆括号、方括号、花括号等)是否正确匹配。使用栈可以帮助跟踪未匹配的括号。
后缀表达式(逆波兰表示法)求值
后缀表达式是一种没有括号,运算符位于操作数之后的数学表达式表示法。栈可以用来顺序处理表达式中的元素,便于计算最终结果。
前缀、中缀和后缀表达式的转换
栈可以用于不同类型的数学表达式之间的转换,特别是在将中缀表达式转换为前缀或后缀表达式时。
浏览器的前进和后退功能
栈可以模拟Web浏览器中的页面访问历史,支持前进和后退操作。
递归函数的模拟
栈可以用来模拟递归函数的调用过程,尤其是在需要将递归算法转换为非递归形式时。
路径和迷宫问题
在求解路径问题(如迷宫探索)时,栈可以用来存储从起点到当前位置的路径。
深度优先搜索(DFS)
在图和树的深度优先搜索中,栈用于跟踪待探索的顶点。
字符串处理
例如,使用栈解决字符串中的所有相邻重复项删除问题,或者字符串翻转问题。
函数调用栈
在编程语言的实现中,栈用于跟踪函数调用和局部变量的作用域。
逆波兰计算器
实现一个简单的文本界面计算器,支持基本的数学运算,输入为后缀表达式形式。
20. 有效的括号
Problem: 20. 有效的括号
1.思路
栈
2.Code
class Solution {
public:
bool isValid(string s) {
stack<char> st;
for(auto c :s){
if(c == '(' || c == '[' || c == '{'){
st.push(c);
}else{
if(st.empty()) return false;
char cur = st.top();
if(cur == '(' && c != ')') return false;
if(cur == '[' && c != ']') return false;
if(cur == '{' && c != '}') return false;
st.pop();
}
}
if(st.empty()) return true;
else return false;
}
};
1047. 删除字符串中的所有相邻重复项
Problem: 1047. 删除字符串中的所有相邻重复项
1.思路
栈:从后向前遍历s,是为了让越靠前的字符靠近栈顶,越往后的的字符靠近栈底(所以后面的字符先入栈)
思路是,当栈为空时,向栈中压入字符,当栈非空时,判断当前遍历的字符是否与栈顶字符相等(因为这时的栈顶字符和当前遍历的字符就是相邻的字符),相等就删除栈顶(删除相邻的相等字符),不想等就直接入栈。
2.Code
class Solution {
public:
string removeDuplicates(string s) {
// abbaca
// aaca
// ca
stack<char> st;
if(s.size()==1) return s;
for(int i = s.size() - 1; i >= 0; i--){
if(st.empty()){
st.push(s[i]);
}else{
char last = st.top();
if(last == s[i]) st.pop();
else st.push(s[i]);
}
}
string new_s = "";
while(!st.empty()){
new_s += st.top();
st.pop();
}
return new_s;
}
};
150. 逆波兰表达式求值
Problem: 150. 逆波兰表达式求值
1.思路
栈
第一次写的时候isNum没有考虑到负数的情况
2.Code
class Solution {
public:
int evalRPN(vector<string>& tokens) {
// 逆波兰表示法 后缀表达式 运算符在操作数的后面
//2 3
//1
//+
stack<int> st;
for(auto s : tokens){
if(isNum(s)){
st.push(toNum(s));
}else{
int r = st.top();
st.pop();
int l = st.top();
st.pop();
if(s=="+") st.push(l + r);
else if(s=="-") st.push(l - r);
else if(s=="*") st.push(l * r);
else if(s=="/") st.push(l / r);
}
}
return st.top();
}
bool isNum(string s){//没有考虑到负数的问题
if(s != "+" && s!= "-" && s!= "*" && s!= "/") return true;
return false;
}
int toNum(string s){
int num = 0;
if(s[0]=='-'){
for(int i = 1; i < s.size(); i++){
num = num * 10 + (s[i] - '0');
}
return num *= -1;
}else{
for(int i = 0; i < s.size(); i++){
num = num * 10 + (s[i] - '0');
}
return num;
}
}
};