题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
- 有效字符串需满足:
-
左括号必须用相同类型的右括号闭合。
-
左括号必须以正确的顺序闭合。
-
- 来自:
思路
要使用栈
以如下字符串为例分析
const str = "{([])}"
遇到左括号时,还没有办法判断是否匹配,需要遇到右括号时,才能去判断是否是一对括号。
最好提前做一个左右括号的映射表,遇到左括号时,把对应的右括号放入栈里,作为预期目标 在遇到右括号时,取出栈里的括号,判断两个括号是否相等即可
const map = new Map([
['(', ')'],
['[', ']'],
['{', '}'],
])
// 第一个括号匹配流程如下
const targetRight = map.get('(')
const stack = []
stack.push(targetRight) // [')']
const testRightCh = ')'
// 判断出栈的括号是否与待测括号匹配
stack.pop() === testRightCh
匹配失败情况:
- 遍历字符串过程中,匹配右括号时
- 栈为空,说明之前没有出现过对应的左括号,但是后面出现右括号
- 出栈的括号与当前括号不相等
- 遍历字符串结束后
- 栈中还有元素,说明有部分左括号没有匹配的右括号
代码实现思路
- 建立括号映射表
- 遍历字符串,取出每个字符
- 判断是左括号,左括号对应的右括号入栈
- 是右括号
- 栈为空,失败
- 出栈的元素与右括号不相等,失败
- 遍历结束,判断栈里是否为空栈
- 如果是空栈,全部匹配成功;
- 否则,有部分括号没有匹配,失败
/**
* @param {string} s 待匹配的字符串
* @return {boolean} 匹配结果
*/
const isValid = function (s) {
// 左-右括号映射表
const map = new Map([
['(', ')'],
['[', ']'],
['{', '}']
])
// 存储左括号的对应右括号
const stack = []
// 遍历字符串,取出一个字符串
for (const c of s) {
// 是左括号(键值间接判断的)
if (map.has(c)) {
// 取出对应的右括号入栈,后面遇到右括号时,直接比较就可以了
stack.push(map.get(c))
} else {
// 遇到右括号
// 栈为空 或者 出栈元素和当前右括号不匹配
if (stack.length === 0 || stack.pop() !== c) {
return false
}
}
}
// 栈为空,全部匹配成功,否则,有部分左括号没有匹配,匹配失败
return stack.length === 0 ? true : false
}