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

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

时间:2022-11-29 12:34:09浏览次数:63  
标签:第十一天 deque ch 随想录 pop else 括号 求值 stack

今日内容:

● 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用户

标签:第十一天,deque,ch,随想录,pop,else,括号,求值,stack
From: https://www.cnblogs.com/gaoyuan2lty/p/16935091.html

相关文章

  • 代码随想录Day31
    LeetCode700.二叉搜索树中的搜索给定二叉搜索树(BST)的根节点和一个值。你需要在BST中找到节点值等于给定值的节点。返回以该节点为根的子树。如果节点不存在,则返回NULL......
  • 代码随想录算法训练营Day10|232. 用栈实现队列、225. 用队列实现栈
    代码随想录算法训练营Day10|232.用栈实现队列、225.用队列实现栈232.用栈实现队列题目链接:232.用栈实现队列题目要求"假设所有操作都是有效的(例如,一个空的队列不会......
  • 代码随想录训练营第四十六天 | 动态规划
    今天是第四十六天,动态规划周的最后一天 139.单词拆分classSolution{publicbooleanwordBreak(Strings,List<String>wordDict){intn=s.lengt......
  • 代码随想录第四十五天 | 动态规划
    今天是第四十五天,继续动态规划 70.爬楼梯(进阶)classSolution{publicintclimbStairs(intn){int[]dp=newint[n+1];dp[0......
  • 代码随想录Day30
    LeetCode617 合并二叉树给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果......
  • 中缀表达式求值
    中缀表达式指的是形如(15+(32-1)×5+14÷2)的表达式,这种就是我们通常见到的书写算式顺序,但在实际的计算机运算中要计算中缀表达式则首先要将字符串转换为后缀表达式,然后......
  • 代码随想录训练营第四十三天 | 动态规划背包问题
     今天是第四十三天,还是背包问题1049.最后一块石头的重量II classSolution{publicintlastStoneWeightII(int[]stones){intn=stones.lengt......
  • 代码随想录——链表
    移除链表元素题目简单注意:头节点也要删除时的处理方式下面第三种方法,连续几个都为要删除的节点时要注意/***添加虚节点方式*时间复杂度O(n)*空间复杂度......
  • 代码随想录算法训练营第四天| 24. 两两交换链表中的节点 19.删除链表的倒数第N个节
    24.两两交换链表中的节点classSolution{publicListNodeswapPairs(ListNodehead){if(head==null||head.next==null){returnhe......
  • 代码随想录Day29
    LeetCode654.最大二叉树给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构......