【Leetcode】20. 有效的括号

491 阅读2分钟

题目描述

在这里插入图片描述

// 20. 有效的括号

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

// 有效字符串需满足:

// 左括号必须用相同类型的右括号闭合。
// 左括号必须以正确的顺序闭合。

题解

// 栈辅助法

// s长度记为len,首先排除特殊情况,s为空,或者长度为奇数,直接false。
// 为了方便遍历s,把s转化成char[] 记为strs。
// 由于strs的括号存在 []() 这种左右直接排列,也存在 [()] 这种中央向外扩散的排列,
// 还存在两种的组合 [()]{} 。我们只能死死抓住“遍历的右括号的匹配必为上一次遍历的左
// 括号“这一点。而这种特性正好符合栈stack的规则。
// 创建一个栈stack,把我们遍历到的所有左括号存入stack中,一旦遍历到右括号,
// 直接把栈顶的括号返回,如果s能够正确闭合,栈顶返回的左括号一定跟遍历的右括号,
// 匹配,如果不匹配直接false。因此我们还要构筑匹配关系表,方便我们匹配左右括号。
// 构建HashMap记为map,存储括号对应关系,我们希望在遍历括号的时候,把得到的括号
// 直接拿来和对应的另一边括号来匹配。因为我们存进stack中的是左括号(先出现的是左)
// 所以需要匹配是左括号,我们就把右括号作为key,对应的左括号作为value,存入map中。
//
// 从左到右for循环遍历strs,遍历元素为strs[i],如果strs[i]不在map的key中,
// 说明是左括号,存入stack。否则肯定是右括号,检查stack是否为空(排除strs中
// 全为右括号的情况),stack为空直接false。
// 检查完,将stack中上一次遍历左括号temp弹出栈顶,如果strs[i]在map中的匹配括号
// 等于temp,匹配成功,继续遍历。否则直接false。
// 循环结束后返回stack是否为空的判断(排序strs中全为左括号的情况)。
// 
// 执行用时:2 ms, 在所有 Java 提交中击败了76.11%的用户
// 内存消耗:36.9 MB, 在所有 Java 提交中击败了10.83%的用户
import java.util.HashMap;
import java.util.Stack;
class Solution {
    public boolean isValid(String s) {
        int len = s.length();
        if (s == null || len == 0 || len % 2 == 1)
            return false;

        Stack<Character> stack = new Stack<>();
        char[] strs = s.toCharArray();
        HashMap<Character, Character> map = new HashMap<>();
        map.put(')', '(');
        map.put(']', '[');
        map.put('}', '{');

        for (int i = 0; i < len; i++) {
            if (!map.containsKey(strs[i]))
                stack.push(strs[i]);
            else {
                if (stack.isEmpty())
                    return false;
                Character temp = stack.pop();    
                if (!temp.equals(map.get(strs[i])))
                    return false;
            }
        }

        return stack.isEmpty();
    }
}