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

今日内容:

20. 有效的括号

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

150. 逆波兰表达式求值

详细布置

20. 有效的括号

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

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

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

分析一下 这里有三种不匹配的情况,

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。
  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配

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

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

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

class Solution {
          public boolean isValid(String s) {
              Deque<Character> deque = new LinkedList<>();
              char ch;
              for (int i = 0; i < s.length(); i++) {
                  ch = s.charAt(i);
                  //碰到左括号,就把相应的右括号入栈
                  if (ch == '(') {
                      deque.push(')');
                  } else if (ch == '[') {
                      deque.push(']');
                  } else if (ch == '{') {
                      deque.push('}');
                  } else if (deque.isEmpty() || deque.peek() != ch) {
                      return false;
                  } else {//若是右括号则判断是否和栈顶元素匹配
                      deque.pop();
                  }
              }
              //最后判断栈中元素是否匹配
              return deque.isEmpty();
          }
      }
info
			解答成功:
			执行耗时:1 ms,击败了98.90% 的Java用户
			内存消耗:39.8 MB,击败了21.78% 的Java用户

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) {
        ArrayDeque<Character> deque = new ArrayDeque<>();
        char ch;
        for (int i = 0; i < s.length(); i++) {
            ch = s.charAt(i);
            if (deque.isEmpty() || deque.peek() != ch){
                deque.push(ch);
            }else {
                deque.pop();
            }
        }
        String str = "";
        while(!deque.isEmpty()){
            str = deque.pop() + str;
        }
        return str;
    }
}
info
			解答成功:
			执行耗时:141 ms,击败了28.04% 的Java用户
			内存消耗:43.6 MB,击败了16.17% 的Java用户
class Solution {
    public String removeDuplicates(String s) {
        //将 res 当栈
        StringBuffer res = new StringBuffer();
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
            if (top >= 0 && res.charAt(top) == c) {
                res.deleteCharAt(top);
                top--;
            // 否则,将该字符 入栈,同时top++
            } else {
                res.append(c);
                top++;
            }
        }
        return res.toString();
    }
}
info
			解答成功:
			执行耗时:22 ms,击败了70.79% 的Java用户
			内存消耗:41.9 MB,击败了73.84% 的Java用户

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

思路

《代码随想录》算法视频公开课:栈的最后表演! | LeetCode:150. 逆波兰表达式求值(opens new window),相信结合视频在看本篇题解,更有助于大家对本题的理解。

在上一篇文章中1047.删除字符串中的所有相邻重复项(opens new window)提到了 递归就是用栈来实现的。

所以栈与递归之间在某种程度上是可以转换的! 这一点我们在后续讲解二叉树的时候,会更详细的讲解到。

那么来看一下本题,其实逆波兰表达式相当于是二叉树中的后序遍历。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList<>();
        for (String s: tokens) {
            if ("+".equals(s)){
                stack.push(stack.pop() + stack.pop());
            }else if ("-".equals(s)) {
                stack.push(-stack.pop() + stack.pop());
            } else if ("*".equals(s)) {
                stack.push(stack.pop() * stack.pop());
            } else if ("/".equals(s)) {
                int temp1 = stack.pop();
                int temp2 = stack.pop();
                stack.push(temp2 / temp1);
            } else {
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}
info
			解答成功:
			执行耗时:5 ms,击败了93.61% 的Java用户
			内存消耗:41 MB,击败了70.33% 的Java用户
posted @ 2022-11-29 12:22  染醉霜林  阅读(28)  评论(0)    收藏  举报