代码随想录算法训练营第十一天

20. 有效的括号

力扣原题链接

思路:用栈来模拟,分出三种不匹配的情况:

  1. 左括号多了;
  2. 最临近的左右括号不匹配;
  3. 右括号多了。

针对这三种情况做出对应的判断即可。

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Stack;

public class is_Valid {

    public boolean isValid(String s) {
        if (s.length() % 2 != 0) return false;
//        Stack<Character> stack = new Stack<Character>();
        Deque<Character> deque = new ArrayDeque<>();
        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() || ch != deque.peek()) {  // 判断第3种和第2种情况
                return false;
            } else {
                deque.pop();  // 如果是右括号判断是否和栈顶元素匹配
            }
        }
        return deque.isEmpty();  // 判断第3种情况
    }

}

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

力扣原题链接
栈的经典应用。

要知道栈为什么适合做这种类似于爱消除的操作,因为栈帮助我们记录了 遍历数组当前元素时候,前一个元素是什么。

思路1:使用 Deque 作为堆栈。

public String removeDuplicates(String s) {
        // ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
        Deque<Character> stack = new ArrayDeque<>();
        char ch;
        for (int i = 0; i < s.length(); i++) {
            ch = s.charAt(i);
            if (stack.isEmpty() || stack.peek() != ch) {
                stack.push(ch);
            } else {
                stack.pop();
            }
        }
        String str = "";
        while (!stack.isEmpty()) {
            str = stack.pop() + str;
        }
        return str;
    }

思路2:拿字符串直接作为栈,省去了栈还要转为字符串的操作。

public String removeDuplicates(String s) {
    StringBuilder res = new StringBuilder();
    int top = -1;  // top为 res 的长度
    for (int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        // 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
        if (top >= 0 && res.charAt(top) == ch) {
            res.deleteCharAt(top);
            top--;
        } else {  // 否则,将该字符 入栈,同时top++
            res.append(ch);
            top++;
        }
    }
    return res.toString();
}

150. 逆波兰表达式求值

力扣原题链接

思路:逆波兰表达式为二叉树的后序遍历(左右中),声明一个 Integer 的栈,然后遍历给出的字符串数组,如遇运算符则弹出栈顶两元素做运算,其他情况就是遇到“数字”,这时 push 到栈里即可(记得将String 转换成 Integer),最后取出栈顶元素即为表达式的值。

public static int evalRPN(String[] tokens) {
        Deque<Integer> stack = new ArrayDeque<>();
        for (String token : tokens) {  // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
            if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {
                int num2 = stack.pop();
                int num1 = stack.pop();
                if (token.equals("+")) stack.push(num1 + num2);
                if (token.equals("-")) stack.push(num1 - num2);
                if (token.equals("*")) stack.push(num1 * num2);
                if (token.equals("/")) stack.push(num1 / num2);
            } else {
//                stack.push(Integer.valueOf(token));
                stack.push(new Integer(token));
            }
        }
        return stack.pop();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值