每日一题:有效的括号

191 阅读2分钟

括号匹配

题目

一个字符串内部可能包含 { } ( ) [ ] 三种括号,判断该字符串是否是括号匹配的。
(a{b}c) 就是匹配的, {a(b{a(b}c) 就是不匹配的。

栈 Stack

该题目的考察目的很明确 —— 栈

栈,先进后出,基本的 API

  • push
  • pop
  • length

和栈相关的数据结构(后面讲)

  • 队列,先进先出
  • 堆,如常说的“堆栈模型”

逻辑结构和物理结构

栈和数组有什么区别?—— 没有可比性,两者不一个级别。就像:房子和石头有什么区别?

栈是一种逻辑结构,一种理论模型,它可以脱离编程语言单独讲。
数组是一种物理结构,代码的实现,不同的语言,数组语法是不一样的。

栈可以用数组来表达,也可以用链表来表达,也可以自定义 class MyStack {...} 自己实现…
在 JS 中,栈一般情况下用数组实现。

思路

  • 遇到左括号 { ( [ 则压栈
  • 遇到右括号 } ) ] 则判断栈顶,相同的则出栈
  • 最后判断栈 length 是否为 0

答案

普通解法

/**
 * 判断左右括号是否匹配
 * @param left 左括号
 * @param right 右括号
 */
function isMatch(left: string, right: string): boolean {
    if (left === '{' && right === '}') return true
    if (left === '[' && right === ']') return true
    if (left === '(' && right === ')') return true
    return false
}

/**
 * 判断是否括号匹配
 * @param str str
 */
export function matchBracket(str: string): boolean {
    const length = str.length
    if (length === 0) return true

    const stack = []

    const leftSymbols = '{[('
    const rightSymbols = '}])'

    for (let i = 0; i < length; i++) {
        const s = str[i]

        if (leftSymbols.includes(s)) {
            // 左括号,压栈
            stack.push(s)
        } else if (rightSymbols.includes(s)) {
            // 右括号,判断栈顶(是否出栈)
            const top = stack[stack.length - 1]
            if (isMatch(top, s)) {
                stack.pop()
            } else {
                return false
            }
        }
    }

    return stack.length === 0
}

ES6解法

使用MAP数据结构优化代码逻辑,减少代码量。对应力扣:20. 有效的括号 - 力扣(LeetCode) (leetcode-cn.com)

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    if(s.length % 2 === 1) return false // 优化,如果为奇数则不符合要求
    const stack = []
    const matchString = new Map([
        [')', '('],
        [']', '['],
        ['}', '{']
    ])
    for(let str of s) {
        const top = stack[stack.length - 1]
         if(matchString.has(str)) {
             if(matchString.get(str) === top) {
                 stack.pop()
             } else {
                 return false
             }
         } else {
             stack.push(str)
         }
    }
    return stack.length === 0
};

划重点

  • 逻辑结构和物理结构