算法训练营day11(栈和队列02:有效括号,删除字符串相邻重复项,逆波兰表达式求值)

第五章 栈与队列part02
今日内容: 
 
● 20. 有效的括号
● 1047. 删除字符串中的所有相邻重复项
● 150. 逆波兰表达式求值
 
 详细布置 
 
 20. 有效的括号 
 
讲完了栈实现队列,队列实现栈,接下来就是栈的经典应用了。 
 
大家先自己思考一下 有哪些不匹配的场景,在看视频 我讲的都有哪些场景,落实到代码其实就容易很多了。
 
题目链接/文章讲解/视频讲解:https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html  
 
 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
 
 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

day 11

有效的括号

栈方法

 class Solution {
     public boolean isValid(String s) {
         if( s.length() % 2 != 0) return false;
         //剪枝
         Deque<Character> stack = new LinkedList<>();//用linkedList链表实现Deque来当做stack栈...尼玛
       //Deque方法有push(),pop(),peek(),ipush(),pop(),peek(),ipeek(),idEmpty()DequedEmpty()
         for( int i = 0; i< s.length(); i++){
             char ch = s.charAt(i);
             if( ch == '('){
                 stack.push(')');
             }else if( ch == '['){
                 stack.push(']');
             }else if( ch == '{'){
                 stack.push('}');
             }
             //else if( ch == ')' || ch == ']' || ch == '}' ){
             else if( stack.isEmpty() || ch != stack.peek()){
                 return false;
             }else if( ch == stack.peek()){
                 stack.pop();
             }
         }
         return stack.isEmpty();
     }
 }

删除字符串重复的相邻项

法一:Linkedlsit赋给Deque当stack

 class Solution {
     public String removeDuplicates(String s) {
         Deque<Character> stack = new LinkedList<>();
         for( int i = 0; i < s.length(); i++){
             char ch = s.charAt(i);
             if( stack.isEmpty() || ch != stack.peek() ){//如果是空的就push进去,如果和顶元素不同就push进去
                 stack.push(ch);
             }else {//stack不空而且 ch == stack.peek(),弹出
                 stack.pop();
             }
         }
         String str = "";//栈转为字符串
         while( !stack.isEmpty()){
             str = stack.pop() + str;
         }
         return str;
     }
 }

法二:字符串做stack

 class Solution {
     public String removeDuplicates(String s) {
         StringBuffer res = new StringBuffer();
         int top = -1;
         //用字符串当栈,top用来当栈顶元素下标,为-1说明栈为空;
         //StringBuffer有append()方法和deleteCharAt(top)方法;
         for (int i =0; i < s.length(); i++){
             char ch = s.charAt(i);
             if( top < 0 ||  ch != res.charAt(top)){
                 res.append(ch);
                 top++;
             }else{
                 res.deleteCharAt(top);
                 top--;
             }
         }
         return res.toString();//转换为字符串方便
     }
 }

逆波兰表达式求值

栈(错误做法)

 //以下做法错误
 class Solution {
     public int evalRPN(String[] tokens) {
         Deque<Character> stack = new LinkedList<>();
         for( int i = 0; i < tokens.length; i++){//对数组来说length是属性而不是方法
             String token = tokens[i];
             if( tokens.equals("+") ){//字符串不能用 == 判断,需要用.equals()方法
                 stack.push( (char)((int)stack.pop() +(int) stack.pop()));
               //当数字变成几十的时候就没办法转成char了,所以Deque应该是个Integer类型的栈,因此本做法错误
             }else if( tokens.equals("-") ){
                 stack.push( (char)((int)stack.pop() - (int)stack.pop()));
             }else if(tokens.equals("*") ){
                 stack.push( (char)((int)stack.pop() * (int)stack.pop()));
             }else if( tokens.equals("/") ){
                 stack.push( (char)((int)stack.pop() / (int)stack.pop()));
             }else{
                 stack.push(token.charAt(0));
             }
         }
         return (int)stack.pop();
     }
 }

栈(正确做法)

其实细节还真是挺多的

 class Solution {
     public int evalRPN(String[] tokens) {
         Deque<Integer> stack = new LinkedList();
         for (String s : tokens) {
             if ("+".equals(s)) {        // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
                 stack.push(stack.pop() + stack.pop());      // 注意 - 和/ 需要特殊处理
                 //具体的:表达式 5 3 - 在逆波兰表示法中表示 5 - 3,而不是 3 - 5
                 //所以第一个弹出来的是第二个操作数,第二个弹出来的是第一个操作数
             } 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));
                 //Integer.valueOf(s) 尝试将字符串 s 转换为 Integer 对象
 //如果 s 是一个有效的整数字符串(例如 "123", "-456", "0"),则 Integer.valueOf(s) 将成功执行并返回相应的 Integer 对象
 //如果 s 不能被转换为有效的整数(例如 "abc", "", "123.45"),则会抛出 NumberFormatException 异常,此时方法返回 false
             }
         }
         return stack.pop();
     }
 }

注:感谢大佬分享

代码随想录-算法训练营day11【栈与队列02:有效的括号、删除字符串中的所有相邻重复项、逆波兰表达式求值】_删除字符串中的所有相邻重复项linkedlist-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值