代码随想录算法训练营第天十一天丨 栈与队列part02

文档讲解:代码随想录

状态:已完成

20. 有效的括号

思路

题意其实就像我们在写代码的过程中,要求括号的顺序是一样的,有左括号,相应的位置必须要有右括号。

由于栈结构的特殊性,非常适合做对称匹配类的题目。

首先要弄清楚,字符串里的括号不匹配有几种情况。

一些同学,在面试中看到这种题目上来就开始写代码,然后就越写越乱。

建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。

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

1.第一种情况,字符串里左方向的括号多余了 ,所以不匹配。

代码随想录算法训练营第天十一天丨 栈与队列part02_第1张图片

2.第二种情况,括号没有多余,但是 括号的类型没有匹配上

 代码随想录算法训练营第天十一天丨 栈与队列part02_第2张图片

3.第三种情况,字符串里右方向的括号多余了,所以不匹配。

代码随想录算法训练营第天十一天丨 栈与队列part02_第3张图片

我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

动画如下:

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

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

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

class Solution {
    public boolean isValid(String s) {
        //进行剪枝操作,如果传入的字符串的长度为奇数,那他最后一定匹配不上
        if (s.length() % 2 != 0){return false;}
        Stack stack = new Stack();

        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 (stack.isEmpty() || stack.peek() != ch){return false;}
            else {stack.pop();}//如果是右括号判断是否和栈顶元素匹配
        }
        //最后判断栈中元素是否匹配
        return stack.isEmpty();
    }
}

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

思路

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?

所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。

然后再去做对应的消除操作。 如动画所示:

代码随想录算法训练营第天十一天丨 栈与队列part02_第4张图片

从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。

class Solution {
    public String removeDuplicates(String s) {
        Stack stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (stack.isEmpty() || stack.peek() != ch){
                stack.push(ch);
            } else if (stack.peek() == ch) {
                stack.pop();
            }
        }
        String str = "";
        int count = stack.size();
        while (count > 0){
            count--;
            str = stack.pop() + str;
        }
        return str;
    }
}

150. 逆波兰表达式求值

思路

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

本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么这岂不就是一个相邻字符串消除的过程,和1047.删除字符串中的所有相邻重复项 (opens new window)中的对对碰游戏是不是就非常像了。

class Solution {
    public static int evalRPN(String[] tokens) {
        Stack stack = new Stack<>();
        for (String str : tokens) {
            if (str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/")){
                Integer num1 = stack.pop();
                Integer num2 = stack.pop();
                if (str.equals("+")){
                    stack.push(num1 + num2);
                }
                if (str.equals("-")){
                    stack.push(num2 - num1);
                }
                if (str.equals("*")){
                    stack.push(num1 * num2);
                }
                if (str.equals("/")){
                    stack.push(num2 / num1);
                }
            }else {
                stack.push(Integer.valueOf(str));
            }
        }
        return stack.pop();
    }
}

以上为我做题时候的相关思路,语言组织能力较弱,有错误望指正。

你可能感兴趣的:(代码随想录算法训练营,算法)