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

20.有效的括号

题目链接:https://leetcode.cn/problems/valid-parentheses/description/

视频链接:https://www.bilibili.com/video/BV1AF411w78g/?spm_id_from=333.788&vd_source=80cf8293f27c076730af6c32ceeb2689

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

三种不匹配的情况

  1. 多了左括号

例如:( [ { } ] ( )

  1. 括号类型不匹配

例如:[ { ( ] } ]

  1. 多了右括号

例如:[ { } ] ( ) ) ) )

思路

**遇到左括号,就把对应的右括号放进栈里。**到时候匹配的时候直接弹出来和元素做比较就行。如果遇到左括号放左括号,弹出的时候还要做判断,对应的是右括号,对类型进行判断。

遇到右括号了,就和栈顶元素进行比较,相等就弹出。

有几种可能:

  1. 如果遍历完后栈不为空,说明左括号多了,不匹配。

  2. 如果在遍历过程中发现了与栈顶元素不匹配的括号,说明括号类型不匹配。

  3. 如果还没遍历完,栈就空了,说明右括号多了,不匹配。

在这里插入图片描述

java代码

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        char ch;
        for(int i = 0; i < s.length(); i++) {
            ch = s.charAt(i);
            if(ch == '(') stack.push(')');
            else if(ch == '[') stack.push(']');
            else if(ch == '{') stack.push('}');
            else if(stack.empty() || stack.peek() != ch)  //遇到了右括号,栈顶元素不匹配 or 还没匹配完栈空了
                return false;
            else stack.pop();
        }
        if(!stack.empty()) return false; //匹配完了栈里还有元素
        return true;
    }
}
  • 首先看到题先想到三种不匹配的情况。遇到右括号栈顶不匹配还没匹配完栈就空了都是在遍历的过程中直接判断return false。这两种如果合在一起写,一定要先判断是否为空!因为顺序从左到右,如果对空栈peek()会报错!!!
  • 匹配完了栈不为空是在遍历完之后判断。

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

题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/

视频链接:https://www.bilibili.com/video/BV12a411P7mw/?spm_id_from=333.788&vd_source=80cf8293f27c076730af6c32ceeb2689

讲解链接: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#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

思路

还是栈的应用。上一题就是用栈来进行匹配操作。这题一样是遍历字符串,遍历到一个就找当前栈顶有没有和它相同的,没有就放进去。有相同的就弹出,同时遍历下一个。(这其实就是消除操作了)

**栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。**然后做消除操作。

从栈里弹出剩余的元素,因为是倒序的(栈是先进后出),还要反转一次字符串。

在这里插入图片描述

遍历过程中:

  • 如果栈为空 直接入栈
  • 如果栈不空,不等于栈顶元素,入栈
  • 如果栈不空,等于栈顶元素,弹出(相当于消除)

最后依次弹出,然后倒序(也可以每次str = st.pop() + str 相当于前插)

java代码

class Solution {
    public String removeDuplicates(String s) {
        Stack<Character> stack = new Stack<>();
        for(int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if(stack.empty()) {
                stack.push(ch); 
            }
            else if(stack.peek() == ch) {  //和栈顶元素相同就弹出(i++ 也就是消除)
                stack.pop();
            }
            else stack.push(ch);
        }
        String str = "";
        while (!stack.empty()) {
            str = stack.pop() + str;
        }
        return str;
    }
}
  • 用ArrayDeque代替stack会更快!

ArrayDeque<Character> deque = new ArrayDeque<>();

注意判空是isEmpty(),其他和stack一样!

150. 逆波兰表达式求值

题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/

视频链接:https://www.bilibili.com/video/BV1kd4y1o7on/?spm_id_from=333.788&vd_source=80cf8293f27c076730af6c32ceeb2689

讲解链接: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#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

思路

逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。

栈与递归之间在某种程度上是可以转换的!

其实逆波兰表达式相当于是二叉树中的后序遍历

  • 操作过程:

遇见数字就入栈,遇见操作符就从栈里取出两个元素做运算,然后把结果入栈。

栈里剩下的元素就是最后的结果。

在这里插入图片描述

java代码

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> st = new Stack<>();
        for(String s : tokens) {
            if(s.equals("+")) {
                st.push(st.pop() + st.pop());
            } else if(s.equals("-")) {
                st.push(-st.pop() + st.pop());
            } else if(s.equals("*")) {
                st.push(st.pop() * st.pop());
            } else if(s.equals("/")) {
                int tmp1 = st.pop();
                int tmp2 = st.pop();
                st.push(tmp2 / tmp1);
            } else st.push(Integer.valueOf(s)); //遇到数字就转换成int 再入栈!
        }
        return st.pop();
    }
}
  • 注意题目给的是一个String数组!我们要用.equals()判断(力扣不能用==!!!)

  • String转数字用Integer.valueOf(s)。遇到数字就先转成数字再入栈,之后计算就不用转了!

  • 遍历字符串数组可以用for(String s : token)

  • -/ 操作需要特殊处理,注意顺序,先取出来的是减数/除数,后取出来的才是被减数/被除数!!!

day11总结

  • 相邻字符消除的操作,很多用栈来解决!

  • 栈与递归之间在某种程度上是可以转换的

  • 遍历字符串数组可以用for(String s : token)

  • String转数字用Integer.valueOf(s)

  • deque,尤其是ArrayDeque实现类当做栈比Stack更快!

  • 注意遍历顺序和出栈顺序是相反的!具体实现要变一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值