LeetCode 热题 HOT — 最长有效括号

361 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 9 天,点击查看活动详情

最长有效括号

原题地址

给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。

示例 1:

输入:s = "(()"
输出:2
解释:最长有效括号子串是 "()"

示例 2:

输入:s = ")()())"
输出:4
解释:最长有效括号子串是 "()()"

示例 3:

输入:s = ""
输出:0

提示:

  • 0 <= s.length <= 3 *10410^4
  • s[i]'('')'

思路分析

  1. 真是羞愧,每次遇到这种题目想到的都是粗暴解法。第一反应就是字符串中将所有的有效括号子串罗列出来,然后取那个长度最长的,但是毫无意外,最终又超时了 o(╥﹏╥)o
  2. 那么只能选择别的方式了。这种类型的题目,可以使用动态规划的方法来解决;
  3. 定义一个以 s.length+1 为长度,0 为内容的 res 数组,其中 res[i] 表示 以 s[i-1] 结尾的最长有效括号的子串长度;
  4. 那么,接下来遍历 s,如果遇到左括号 '(' 记录索引压入栈,并且 res[i+1] = 0,因为左括号不可能是有效括号子串的结尾;
  5. 遇到右括号 ')',若栈内有值,则先找到配对的左括号的索引,即弹出栈顶,并且记录以这个右括号为结尾的最长子串长度为 1 + i - left + res[left];否则没有找到匹配的左括号,即 res[i+1] = 0
  6. res 降序排列,返回 res[0] 即可。

AC 代码

/**
 * @param {string} s
 * @return {number}
 */
var longestValidParentheses = function(s) {
    let stack = [];
    let res = new Array(s.length + 1).fill(0)
    for (let i = 0; i < s.length; i++) {
        if (s.charAt(i) == "(") {
            stack.push(i);
            res[i + 1] = 0;
        } else {
            if (stack.length) {
                let left = stack.pop();
                let len = 1 + i - left + res[left];
                res[i + 1] = len;
            } else {
                res[i + 1] = 0;
            }
        }
    }
    return res.sort((a, b) => b - a)[0]
};

结果:

  • 执行结果: 通过
  • 执行用时:148 ms, 在所有 JavaScript 提交中击败了7.34%的用户
  • 内存消耗:47.8 MB, 在所有 JavaScript 提交中击败了5.02%的用户
  • 通过测试用例:231 / 231

END