// 思路
// 本题规则是允许 []() [()]形式 但不允许 [(])形式
// 以及不允许缺少闭合括号 如([] ()]
// 也就是有三种情况
// 1 ([]这样左边括号多了
// 2 ()]这样右边括号多了
// 3 [(])这样左右不匹配
// 利用栈来对左半边括号进行统计 当对应的右半边括号数量和种类与栈中不匹配
// 说明有括号没有闭合
// 顺便说一下为什么要用栈这种结构
// 因为要防止[(])这样的形式 栈的先进后出正好符合[]() [()]形式的闭合规则
// 遇到左半边就将对应的右半边装入栈 遇到右半边就找栈顶的的括号是否符合
function fn(str) {
// 注意 左右闭合的括号 一定是成对出现
// 因此符合的字符串长度一定是偶数
if (str.length % 2 !== 0) {
// 奇数 说明必不符合
return false
}
// 设置栈
let list = []
for (let i = 0; i < str.length; i++) {
// 遍历字符串 找出左半部分 将对应的右半部分填入栈中
if (str[i] === '(') {
list.push(')')
} else if (str[i] === '[') {
list.push(']')
} else if (str[i] === '{') {
list.push('}')
} else if (!list.length || list[list.length - 1] !== str[i]) {
// 前面的if过滤了左半边括号 当前遇到右半边括号
// 栈为空 且 字符串中仍有右半边括号
// 说明左半边括号少了 多了右边括号 符合情况2
// 当前右括号与栈顶存的右括号类别不符
// 说明出现[(])这样闭合括号不符 符合情况3
return false
} else {
// 剩下的就是找到对应右半边括号 将其出栈
list.pop()
}
}
// 当遍历完字符串 栈中仍有剩余 说明左半边括号多了 符合情况1
if (list.length) {
return false
}
// 此时入栈数和出栈数相等 说明字符串符合题目要求
return true
}
// 验证
let str = '()[]{}'
console.log(`${str} 是否完全闭合:` + fn(str)) // true
str = '([)]'
console.log(`${str} 是否完全闭合:` + fn(str)) // false
str = '{[]}'
console.log(`${str} 是否完全闭合:` + fn(str)) // true
console