「力扣」第 20 题:有效的括号(简单)

396 阅读1分钟

思路:

  • 括号匹配问题是栈的典型应用。在遍历的时候,每一个左括号(({[)都需要在右边找到与之匹配的右括号()}])才能称之为「有效」,所以看到左边括号的时候需要先「缓存」起来
  • 分析特殊用例 [{()}] :先缓存的 [ 反而是最后才能确定有与之匹配的 ],这样匹配的顺序符合「后进先出」的规律,因此考虑使用「栈」作为数据结构。

代码 1:

public class Solution {

    public boolean isValid(String s) {
        int len = s.length();
        if (len == 0) {
            return true;
        }
        if ((len % 2) == 1) {
            return false;
        }

        char[] charArray = s.toCharArray();
        Deque<Character> stack = new ArrayDeque<>();
        for (char c:charArray) {
            switch (c) {
                case '(':
                    stack.addLast(')');
                    break;
                case '[':
                    stack.addLast(']');
                    break;
                case '{':
                    stack.addLast('}');
                    break;
                default:
                    if (stack.isEmpty() || stack.removeLast() != c) {
                        return false;
                    }
                    break;
            }
        }
        return stack.isEmpty();
    }
}

复杂度分析

  • 时间复杂度:O(n)O(n)nn 是字符串 s 的长度;
  • 空间复杂度:O(n)O(n),最差情况下,字符串的一半字符字符要进入栈中

还可以把左右括号的匹配关系存在一个哈希表中,增加扩展性。

代码 2:

public class Solution {

    public boolean isValid(String s) {
        int len = s.length();
        if (len == 0) {
            return true;
        }
        // 奇数长度一定不是有效括号
        if ((len % 2) == 1) {
            return false;
        }

        char[] charArray = s.toCharArray();
        Map<Character, Character> hashMap = new HashMap<>();
        hashMap.put(')', '(');
        hashMap.put(']', '[');
        hashMap.put('}', '{');

        Deque<Character> stack = new ArrayDeque<>();
        for (char c : charArray) {
            // 如果遍历到右括号,检查是否匹配
            if (hashMap.containsKey(c)) {
                // 栈为空和栈顶与当前不匹配都不能称之为"有效"
                if (stack.isEmpty() || !hashMap.get(c).equals(stack.removeLast())) {
                    return false;
                }
            } else {
                // 遍历到左括号就加入栈
                stack.addLast(c);
            }
        }
        return stack.isEmpty();
    }
}

复杂度分析(同上)