【刷题笔记】栈和队列1

1 什么是栈?什么是队列?

        栈和队列想必大家已经很熟悉了。栈就是一个先进后出的数据结构,而队列是先进先出的数据结构。具体如下图所示。

        栈和队列是我们解决很多算法问题很好的工具 ,例如,解决树相关问题的时候,经常需要用到栈和队列。所以,我们需要多做一些题,熟悉一下这两个数据结构。

2. 相关题目

20. 有效的括号

这道题目,我曾经在校招面试遇到过,碰到就相当于送分了。

给定一个字符串,这个字符串中只包含'(',')','{','}','[',']' ,判断对号是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。
    public boolean isValid(String s) {
        char[] chars = s.toCharArray();
        Stack<Character> characters = new Stack<>();
        for (int i = 0; i < chars.length; i++) {
            if (!characters.isEmpty() && characters.peek() == chars[i]) {
                characters.pop();
                continue;
            }
            if (chars[i] == '(') {
                characters.push(')');
            } else if (chars[i] == '[') {
                characters.push(']');
            } else if (chars[i] == '{') {
                characters.push('}');
            } else {
                return false;
            }
        }
        return characters.isEmpty();
    }

这道题最好的办法就是用栈去做,当我们遇到'(','{','[',就把')','}',']',遍历的过程中如果碰到')','}',']',就去栈的头找是否和当前字符相同,相同就一起消掉,不相同就属于失效,类似于消消乐。

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

        给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们。在 s 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

     public static String removeDuplicates(String s) {
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            if (!stack.isEmpty() && stack.peek() == s.charAt(i)) {
                stack.pop();
            } else {
                stack.push(s.charAt(i));
            }
        }
        int size = stack.size();
        String result = "";
        for (int i = 0; i < size; i++) {
            result = stack.pop() + result;
        }
        return result;
    }

这道题与上一题类似,先把字母放到栈里面,后面遍历时如果和栈头字母相同,就一起消掉,否则就如栈。

150. 逆波兰表达式求值

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

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

注意:

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

         这道题虽然官网标的是中等题,但是如果用栈来做的话,其实就是简单题难度。大家可能之前不了解逆波兰表达式,所以会不知所措,仔细阅读后就能知道,就是我们在遍历字符串数组的时候,一旦遇到运算符,就把这个运算符前面两个数取出来,进行运算。如果一个字符串数组中出现多个运算符,就需要先把前面的先算出结果来,然后那这个结果去和后面的进行计算,就相当于加了小括号。

        那么我们如何操作呢?

        还是用到栈,先将两个数存到栈里面,然后如果遇到运算符,就把两个数弹出来,根据运算符进行计算,再把计算结果压进栈中;后面如果再来了一个数,紧接着又来了一个运算符,就可以继续把两个数取出来运算,是不是相当于加了小括号呢。

        具体代码如下:

    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        int sum = 0;
        stack.push(Integer.parseInt(tokens[0]));
        for (int i = 1; i < tokens.length; i++) {
            if ("+".equals(tokens[i])) {
                Integer right = stack.pop();
                Integer left = stack.pop();
                stack.push(left + right);
            } else if ("-".equals(tokens[i])) {
                Integer right = stack.pop();
                Integer left = stack.pop();
                stack.push(left - right);
            } else if ("*".equals(tokens[i])) {
                Integer right = stack.pop();
                Integer left = stack.pop();
                stack.push(left * right);
            } else if ("/".equals(tokens[i])) {
                Integer right = stack.pop();
                Integer left = stack.pop();
                stack.push(left / right);
            } else {
                stack.push(Integer.parseInt(tokens[i]));
            }
        }
        return stack.pop();
    }
  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值