LeetCode热题(JS版) - 32. 最长有效括号

99 阅读2分钟

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

题目

示例 1:

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

示例 2:

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

示例 3:

输入:s = ""
输出:0

提示:

0 <= s.length <= 3 \* 104
s\[i] 为 '('')'

思路

通常涉及括号匹配问题的题目都可以考虑使用栈来解决。这道题也不例外。我们创建一个栈,然后遍历字符串中的每个字符。

如果当前字符是左括号 (,那么就将其推入栈中。

如果当前字符是右括号 ),那么我们需要检查栈是否为空。若栈为空,则说明当前的右括号没有合适的左括号与之匹配,直接忽略即可;否则弹出栈顶元素,并计算当前有效匹配的字符串长度。

特别地,对于这道题,我们还需要注意一种情况:即当我们遍历到当前位置时,栈中仍有剩余元素,但已经无法进行匹配时,我们需要将栈中所有元素弹出,并更新最长有效匹配长度。

下面给出基于以上思路的Javascript代码实现,注意每个操作需要检查栈是否为空。

/**
 * @param {string} s
 * @return {number}
 */
var longestValidParentheses = function(s) {
    let stack = [-1];
    let maxLen = 0;
    for (let i = 0; i < s.length; i++) {
        if (s.charAt(i) === '(') {
            stack.push(i); // 将左括号入栈
        } else {
            stack.pop(); // 弹出栈顶元素
            if (stack.length === 0) {
                stack.push(i); // 若栈为空,则将当前右括号入栈(作为下一个合法括号序列的起点)
            } else {
                maxLen = Math.max(maxLen, i - stack[stack.length - 1]); // 栈非空则更新最大长度
            }
        }
    }
    return maxLen;
};
  • 时间复杂度:O(n)O(n),算法中通过遍历字符串一次来处理所有括号,因此时间复杂度为 O(n)O(n),其中 nn 是给定字符串的长度。
  • 空间复杂度:O(n)O(n),空间复杂度取决于使用的栈的大小。在最坏情况下,如果给定的字符串中每个字符都是左括号 (,那么栈将增长到 nn,因此空间复杂度为 O(n)O(n)

image.png