SOURCE

// 思路
// 本题规则是允许 []() [()]形式 但不允许 [(])形式
// 以及不允许缺少闭合括号 如([] ()]
// 也就是有三种情况
// 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 命令行工具 X clear

                    
>
console