代码随想录算法训练营第11天|20.有效的括号【栈】、1047. 删除字符串中的所有相邻重复项【栈】、150. 逆波兰表达式求值【栈】

栈在算法中的应用

(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;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值