leetcode-有效的括号

185 阅读2分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

在家休息了2天,今天是本周第1天上班。积压了挺多事情的,感觉自己有点忙不过来了。晚上听了一个关于MAC实用小工具的分享,发现其实有意思的小技巧还挺多的,以后也要不断去发现,工具让自己“变懒”,把时间花费在更有意义的事情上。

题目

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

有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
  示例 1:
输入:s = "()"
输出:true

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

示例 3:
输入:s = "(]"
输出:false

示例 4:
输入:s = "([)]"
输出:false

示例 5:
输入:s = "{[]}"
输出:true

思路

又是一题更加偏向于数据结构而不是算法思想的题目。
首先理解一下题目,总共有3种括号,如果要字符串合法必须满意以下条件:

  1. 3种括号的左半边出现次数和右半边出现次数必须相等
  2. 对于任何一个右半边括号,在它左边出现的第一个左半边括号必须跟它是可以配对的
    所以,自然而然会想到使用一个栈,如果遇到括号左半边,就进行压栈;如果遇到括号右半边,就弹出跟当前右半边看能否配对,不能配对就肯定是false,如果能配对,就继续遍历下一个。

有2个需要注意的点:

  1. 如果遇到右半边,需要从栈中弹出最上面的元素时,注意一下栈为空的情况
  2. 如果最后遍历完成后,需要判断一下栈是否是空的,如果不是空,证明左半边肯定有多的

Java版本代码

class Solution {
    public boolean isValid(String s) {
        Set<Character> leftSet = new HashSet<>();
        leftSet.add('(');
        leftSet.add('[');
        leftSet.add('{');
        Map<Character, Character> map = new HashMap<>();
        map.put('(', ')');
        map.put('[', ']');
        map.put('{', '}');
        Stack<Character> stack = new Stack<>();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            char c = s.charAt(i);
            if (leftSet.contains(c)) {
                // 如果是括号的左半边,压栈
                stack.push(c);
            } else {
                // 如果不是,需要从栈中弹出最上面的元素比较是否能配对
                if (stack.isEmpty()) {
                    return false;
                }
                char left = stack.pop();
                if (c == map.get(left)) {
                    continue;
                } else {
                    return false;
                }
            }
        }
        if (stack.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }
}