返回

20. 有效的括号

前端

代码随想录 | day11:栈和队列系列

引言:

欢迎来到代码随想录系列文章的第11篇。今天,我们将深入研究栈和队列数据结构的世界,探索三个令人着迷的算法问题:20. 有效的括号、1047. 删除字符串中的相邻重复项和150. 逆波兰表达式求值。让我们踏上这段算法之旅,以创新思维为向导,用清晰的逻辑和引人入胜的语言描绘出解决方案的画面。

问题:

给定一个只包含圆括号 "()"、"{}" 和 "[]" 的字符串,判断它是否有效。

解决方案:

解决这个问题的关键在于利用栈数据结构。我们将遍历输入字符串,如果遇到左括号,则将其压入栈中。如果遇到右括号,我们检查栈顶的元素是否与它匹配。如果是,我们就弹出栈顶元素。否则,字符串无效。这个过程一直持续到字符串结束或栈变为空。

public boolean isValid(String s) {
    Stack<Character> stack = new Stack<>();
    for (char c : s.toCharArray()) {
        if (c == '(' || c == '{' || c == '[') {
            stack.push(c);
        } else {
            if (stack.isEmpty() || !isMatch(stack.pop(), c)) {
                return false;
            }
        }
    }
    return stack.isEmpty();
}

private boolean isMatch(char left, char right) {
    return (left == '(' && right == ')') || (left == '{' && right == '}') || (left == '[' && right == ']');
}

问题:

给定一个字符串,删除所有相邻的重复项,返回结果字符串。

解决方案:

对于这个问题,我们使用了一个栈来存储字符。当我们遇到与栈顶相同的字符时,我们弹出它。否则,我们将其压入栈中。这个过程一直持续到字符串结束。最后,我们将栈中剩余的字符连接起来,形成结果字符串。

public String removeDuplicates(String s) {
    Stack<Character> stack = new Stack<>();
    for (char c : s.toCharArray()) {
        if (!stack.isEmpty() && stack.peek() == c) {
            stack.pop();
        } else {
            stack.push(c);
        }
    }
    StringBuilder sb = new StringBuilder();
    while (!stack.isEmpty()) {
        sb.append(stack.pop());
    }
    return sb.reverse().toString();
}

问题:

给定一个逆波兰表达式(后缀表达式),求其值。

解决方案:

逆波兰表达式是一种后缀表达式,运算符写在操作数之后。要解决这个问题,我们使用了一个栈。当我们遇到一个操作数时,我们将其压入栈中。当我们遇到一个运算符时,我们弹出栈顶的两个元素,执行运算,然后将结果压入栈中。这个过程一直持续到表达式结束。最后,栈中剩下的元素就是表达式的值。

public int evalRPN(String[] tokens) {
    Stack<Integer> stack = new Stack<>();
    for (String token : tokens) {
        if (isOperator(token)) {
            int num1 = stack.pop();
            int num2 = stack.pop();
            int result = calculate(num2, num1, token);
            stack.push(result);
        } else {
            stack.push(Integer.parseInt(token));
        }
    }
    return stack.pop();
}

private boolean isOperator(String token) {
    return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
}

private int calculate(int num1, int num2, String operator) {
    switch (operator) {
        case "+":
            return num1 + num2;
        case "-":
            return num2 - num1;
        case "*":
            return num1 * num2;
        case "/":
            return num2 / num1;
        default:
            throw new IllegalArgumentException("Invalid operator: " + operator);
    }
}