题目描述:给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 注意空字符串可被认为是有效字符串。
示例 1:
输入: “()”
输出: true
var isValid = function(s) {
// 初始化一个哈希表:key为右括号,value为同类型的左括号
const map = new Map([
[")", "("],
["]", "["],
["}", "{"]
])
// 空栈stack[],用来存放左括号
const stack = [];
let flag = false;
// 空字串直接返回true;(空字串长度为奇数,但它是有效的,所以先判断空字串,再判断字符串长度)
if (s === "") {
return true;
}
// 字符串长度为奇数时,return false(左右括号一定成对,所以有效字符串一定为偶数)
else if (s.length % 2 !== 0) {
return false;
} else {
// 利用for循环遍历字符串
for (let i = 0; i < s.length; i++) {
/* 这里一开始用的if(s[i]==="(" || s[i]==="[" || s[i]==="{");
后来发现利用哈希表判断会更快:map.has(s[i])表示遇到的是右括号,
那么把它取反则遇到的是左括号
*/
// 遇到的不是右括号(即遇到了左括号)
if (!map.has(s[i])) {
// 将左括号入栈
stack.push(s[i]);
}
// 遇到了右括号,栈里有左括号且Map.get(右括号)===pop(),即左右括号匹配
else if (stack.length > 0 && map.get(s[i]) === stack.pop()) {
// 这里不能直接返回true,因为后边需要判断栈里是否有未被匹配的左括号,返回true就退出函数了
flag = true;
}
// 括号不匹配,直接返回false
else {
return false;
}
}
// for循环遍历完(即没有出现括号不匹配),
if (stack.length === 0) {
// 栈里没有未被匹配的左括号
flag = true;
} else {
// 栈里还剩未被匹配的左括号
flag = false;
}
return flag;
}
};