算法:有效的括号

354 阅读2分钟

题目描述

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

思路

要使用

以如下字符串为例分析

const str = "{([])}"

image.png

遇到左括号时,还没有办法判断是否匹配,需要遇到右括号时,才能去判断是否是一对括号。

最好提前做一个左右括号的映射表,遇到左括号时,把对应的右括号放入栈里,作为预期目标 在遇到右括号时,取出栈里的括号,判断两个括号是否相等即可

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
 }