# [20] 有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
这道题是一道经典的符号匹配题,涉及到成对抵消的题我们应当首先考虑使用栈来解决。在这道题里有三对符号匹配且有前后关系(即左括号在右括号之前才合法),因此我们再划分符号为左括号和右括号两部分。当然,如果你认定题目不会给你除了这几个符号之外的字符,也可以用左括号与非左括号划分,这样可以减少两个集合的使用,直接用一个map即可。
之后进行遍历,若是左括号,则直接入栈。若是右括号,将之与栈顶元素比较看是否成对,如果不成对或者栈中没有符号则直接返回false,否则将栈顶取出,进入下一次循环。
这里还有一个剪枝的小技巧:如果字符串长度为奇数,则不可能是一个有效的字符串,返回false。
function isValid(s: string): boolean {
if (s.length % 2 !== 0) return false;
const stack = [];
const leftMap: Record<string, string> = {
'(': ')',
'[': ']',
'{': '}'
};
for (let i = 0; i < s.length; i++) {
// 若为左括号,则入栈
if (leftMap[s[i]]) {
stack.push(s[i]);
} else {
// 若为右括号,则与栈顶元素匹配看是否为一对
const temp = stack.pop();
if (leftMap[temp] !== s[i]) return false;
}
}
if (stack.length !== 0) return false;
return true;
}