今日内容:
● 20. 有效的括号
● 1047. 删除字符串中的所有相邻重复项
● 150. 逆波兰表达式求值
详细布置
20. 有效的括号
讲完了栈实现队列,队列实现栈,接下来就是栈的经典应用了。
大家先自己思考一下 有哪些不匹配的场景,在看视频 我讲的都有哪些场景,落实到代码其实就容易很多了。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html
分析一下 这里有三种不匹配的情况,
- 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。
- 第二种情况,括号没有多余,但是 括号的类型没有匹配上。
- 第三种情况,字符串里右方向的括号多余了,所以不匹配
第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以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. 删除字符串中的所有相邻重复项
栈的经典应用。
要知道栈为什么适合做这种类似于爱消除的操作,因为栈帮助我们记录了 遍历数组当前元素时候,前一个元素是什么。
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