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

20. 有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

示例 1:

输入:s = "()"
输出:true

示例 2:

输入:s = "()[]{}"
输出:true

示例 3:

输入:s = "(]"
输出:false

文章讲解:代码随想录

视频讲解:栈的拿手好戏!| LeetCode:20. 有效的括号_哔哩哔哩_bilibili

第一印象:想不到用什么方法,是懵逼的。

看完讲解:知道了两两匹配的情况用栈更合适。

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack;
        stack = new Stack<>();
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '(') {
                stack.push(')');
            } else if (chars[i] == '{') {
                stack.push('}');
            } else if (chars[i] == '[') {
                stack.push(']');
            //  这里包含了两种情况,一种是左括号没有相对应的右括号与之对应
            //  第二种情况是有右括号但是不是相对应的右括号
            } else if (stack.isEmpty() || stack.peek() != chars[i]) {
                return false;
            } else {
                stack.pop();
            }
        } 
        return stack.isEmpty();
    }
}

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

给出由小写字母组成的字符串 S重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

文章讲解:代码随想录

视频讲解:栈的好戏还要继续!| LeetCode:1047. 删除字符串中的所有相邻重复项_哔哩哔哩_bilibili

第一印象:看到这道题目其实也是匹配类型的题目,我第一时间就想到了栈,我用栈做了出来但是栈在最后输出的时候会有些麻烦,因为出栈的时候是反着出,所以我改变思路用了Deque双向队列在完成了这道题目。另外我也有在思考这道题目双指针是否能做,看了讲解之后发现确实可以。

看完讲解:这道题算是有效的括号的拓展了。

栈:

//  使用Deque来实现
class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> deque = new ArrayDeque<>();
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (deque.isEmpty() || chars[i] != deque.getLast()) {
                deque.addLast(chars[i]);
            } else {
                deque.removeLast();
            }
        }
        String str = "";
        while (!deque.isEmpty()) {
            str += deque.removeFirst();
        }
        return str;
    }
}

双指针:

//  使用双指针实现
class Solution {
    public String removeDuplicates(String s) {
        char[] chars = s.toCharArray();
        int fast = 0;
        int slow = 0;
        while (fast < s.length()) {
            chars[slow] = chars[fast];
            if (slow > 0 && chars[slow] == chars[slow - 1]) {
                slow--;
            } else {
                slow++;
            }
            fast++;
        }
        return new String(chars, 0, slow);  //  0表示起始下标,slow表示终止下标
    }
}

150. 逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 '+''-''*' 和 '/' 。
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

示例 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

文章讲解:代码随想录

视频讲解:栈的最后表演! | LeetCode:150. 逆波兰表达式求值_哔哩哔哩_bilibili

第一印象:不明白为什么要用这么复杂的形式来作为计算的表达式。

看完讲解:对于人类来说,日常的表达式更好理解,但对于计算机来说,内存大多是栈式结构,用

逆波兰表达式更适合计算机。

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        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();
    }
}

今日小结:这几道题都是对栈的拓展,加深了对于栈的理解,下次遇到栈相关的题目都不会再害怕了,当然也要经常复习。

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值