LeetCode20、有效的括号

90 阅读2分钟

LeetCode 系列记录我学习算法的过程。

持续创作,加速成长!这是我参与「掘金日新计划 6 月更文挑战」的第 19 天,点击查看活动详情

题目

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

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。

示例:

输入: s = "()"
输出: true

输入: s = "()[]{}"
输出: true

输入: s = "(]"
输出: false

输入: s = "([)]"
输出: false

提示

  • 1 <= s.length <= 104
  • s 仅由括号 '()[]{}' 组成

思路

这题被标为容易,看了下也确实不难,利用一个数组存储未闭合的左括号,然后遍历字符串抵消,最后判断数组长度即可

  • 定义两个对象分别存储左括号和右括号的值映射,同类括号值一致
  • 定义数组 res 存储未闭合的左括号
  • 遍历字符串 s ,如果当前字符为左括号,存入数组第一项
  • 如果当前字符为右括号,且没有未闭合的左括号,返回 false
  • 如果 res 第一项与当前字符对应的值相同,则删除第一项
  • 如果值不同,返回 false

代码实现

/**
 * @param {string} s
 * @return {boolean}
 */
var isValid = function(s) {
    // 左括号对应的值
    const left = { '(': 1, '{': 2, '[': 3 }
    // 右括号对应的值
    const right = { ')': 1, '}': 2, ']': 3 }
    // 存储未被关闭的左括号
    const res = []
    // 遍历字符串s
    for(let c of s) {
        // 如果当前为右括号
        if(right[c]) {
            // 判断是否有未闭合的左括号,无则返回 false
            if(!res.length) return false
            // 有且最近的一个未闭合左括号与当前右括号对应,则消除该左括号
            if(left[res[0]] === right[c]) {
                res.shift()
            } else {
                // 反之不对应则返回false
                return false
            }
        } else {
            // 当前为左括号,则存入 res
            res.unshift(c)
        }
    }
    // 最后判断是否还有未闭合的左括号
    return !res.length
};

image.png

优化

看了几种其他的解法,也记录一下吧

// 解法一
var isValid = function(s) {
    if(s.length % 2 !== 0) return false
    // 映射
    const map = new Map([[')', '('], ['}', '{'], [']', '[']])
    // 存储未被关闭的左括号
    const res = []
    // 遍历字符串s
    for(let c of s) {
        // 如果当前为右括号
        if(map.get(c)) {
            // 判断是否有未闭合的左括号,无则返回 false
            if(!res.length) return false
            // 有且最近的一个未闭合左括号与当前右括号对应,则消除该左括号
            if(map.get(c) === res[0]) {
                res.shift()
            } else {
                // 反之不对应则返回false
                return false
            }
        } else {
            // 当前为左括号,则存入 res
            res.unshift(c)
        }
    }
    // 最后判断是否还有未闭合的左括号
    return !res.length
};

// 解法二
var isValid = function(s) {
    // 存储未被关闭的左括号
    const res = []
    // 遍历字符串s
    for(let c of s) {
        switch(c) {
            case '(':
            case '{':
            case '[':
                res.unshift(c)
                break
            case ')':
                if(res.shift() !== '(') return false
                break
            case '}':
                if(res.shift() !== '{') return false
                break
            case ']':
                if(res.shift() !== '[') return false
                break
        }
    }
    // 最后判断是否还有未闭合的左括号
    return !res.length
};