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

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

20. 有效的括号

讲完了栈实现队列,队列实现栈,接下来就是栈的经典应用了。

大家先自己思考一下 有哪些不匹配的场景,在看视频 我讲的都有哪些场景,落实到代码其实就容易很多了。

题目链接/文章讲解/视频讲解:https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html

class Solution {
public:
    bool isValid(string s) {
        if(s.size()%2!=0) return false;// 如果s的长度为奇数,一定不符合要求

        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('}');
           // 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号 return false
           // 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
            else if(st.empty()||st.top()!=s[i])
            return false;
            else st.pop();
        }
    return st.empty();// 第一种情况:此时我们已经遍历完了字符串,
    //但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true

    }
};

总结
有三种出问题的情况
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 括号匹配1

第二种情况,括号没有多余,但是 括号的类型没有匹配上。 括号匹配2

第三种情况,字符串里右方向的括号多余了,所以不匹配。 括号匹配3

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

动画如下:请添加图片描述

第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。

分析完之后,代码其实就比较好写了,

但还有一些技巧,在匹配左括号的时候,右括号先入栈,就只需要比较当前元素和栈顶相不相等就可以了,比左括号先入栈代码实现要简单的多了!
通过与符合对称的性质,把对称放到堆栈中,在之后的下面操作消除之前对称符号,最后若堆栈为空则结果正确。

1047. 删除字符串中的所有相邻重复项

栈的经典应用。

要知道栈为什么适合做这种类似于爱消除的操作,因为栈帮助我们记录了 遍历数组当前元素时候,前一个元素是什么。

题目链接/文章讲解/视频讲解:https://programmercarl.com/1047.%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E7%9B%B8%E9%82%BB%E9%87%8D%E5%A4%8D%E9%A1%B9.html

class Solution {
public:
    string removeDuplicates(string s) {
        stack<char>str;
        for(char a:s)//定义a元素来遍历数组s
        {
            if(str.empty()||a!=str.top())//判断堆栈是否为空并将当前字符与栈顶比较
            {
                str.push(a);//不相同则放入堆栈中
            }
            else
            {
                str.pop();//把栈顶释放
            }
        }

        string result="";
        while(!str.empty())//筛选出剩下的元素放入result数组中
        {
            result+=str.top();
            str.pop();
        }
    reverse(result.begin(),result.end());//放入数组是反的,所以反转一下。
    return result;

    }
};

总结
原理同上题,也就是字符串中元素与堆栈里面元素的消消乐。

150. 逆波兰表达式求值

本题不难,但第一次做的话,会很难想到,所以先看视频,了解思路再去做题

题目链接/文章讲解/视频讲解:https://programmercarl.com/0150.%E9%80%86%E6%B3%A2%E5%85%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BC.html

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long>st;


        for(int i=0;i<tokens.size();i++)
        {
            if(tokens[i]=="+"||tokens[i]=="-"||tokens[i]=="*"||tokens[i]=="/")
            {
                    long long num1=st.top();
                    st.pop();
                    long long 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(stoll(tokens[i]));
            }
        }
    long long result=st.top();
    st.pop();// 把栈里最后一个元素弹出(其实不弹出也没事)
    return result;
    }
};

总结
知识点:
1、stol()
此函数将在函数调用中作为参数提供的字符串转换为long int。它解析str并将其内容解释为指定基数的整数,并将其作为long int类型的值返回。
2、stoll()
此函数将在函数调用中作为参数提供的字符串转换为long long int。它解析str并将其内容解释为指定基数的整数,并将其作为long long int类型的值返回。

对二叉树的后序遍历,最后解出算法式子,把数字放入堆栈当中,然后遇到算数符,就得到堆栈两个数字并出栈,计算结果再压入到堆栈中进行后续计算。

  • 33
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值