最长有效括号-leetcode

题目描述

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

左右括号匹配,即每个左括号都有对应的右括号将其闭合的字符串是格式正确的,比如 "(()())"

示例 1:

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

示例 2:

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

示例 3:

输入:s = ""
输出:0

提示:

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

解法一

思路:

第一步:明确 dp 数组的含义(至关重要)

定义 dp[i] 表示:以索引 i 结尾的、最长有效括号子串的长度。

第二步:分析基础状态

如果 s[i] 是左括号 '(',它不能作为一个有效括号子串的结尾,有效括号必须以右括号 ')' 结尾。

  • 所以,s[i] == '(' 时,dp[i] = 0
  • 只需要在 s[i] == ')' 时去推导状态转移方程。

第三步:分类讨论,推导状态转移方程

只看 s[i] == ')' 的情况,那么就要看它前面一个字符 s[i-1] 是什么,这里分为两种情况:

情况 1:前面是左括号,即 s[i-1] == '('

长这样:...... ( ) 索引:...... i-1 i

这种是最简单的,s[i-1]s[i] 刚好凑成了一对 ()

  • 这对 () 贡献了 2 的长度。
  • 那这对 () 之前还有没有有效括号呢?有的话也要连起来!之前的有效括号是以 i-2 结尾的,长度为 dp[i-2]
  • 状态转移方程 1: dp[i] = dp[i-2] + 2 (前提是 i >= 2)

情况 2:前面也是右括号,即 s[i-1] == ')'

长这样:...... ) ) 索引:...... i-1 i

这种情况稍微复杂一点。因为 s[i-1]')',它前面可能已经形成了一段有效的括号子串。 以 i-1 结尾的有效括号长度是 dp[i-1]。 我们要想让当前的 s[i](也就是 ')')有效,就必须跨过前面那段已经成型的有效括号,去它前面找有没有对应的 '('

  1. 找匹配的左括号位置: 跳过 dp[i-1] 的长度,那个位置的索引是 pre = i - dp[i-1] - 1
  2. 判断是否匹配: 如果 s[pre] == '(',太好了!当前的 s[i] 和它匹配上了。
    • 匹配上的这一对括号贡献了 2 的长度。
    • 被包在中间的有效括号长度是 dp[i-1]
    • pre 之前,可能还有连着的有效括号(以 pre-1 结尾),长度是 dp[pre-1]dp[i - dp[i-1] - 2]
  3. 状态转移方程 2: dp[i] = dp[i-1] + 2 + dp[i - dp[i-1] - 2] (前提是 pre >= 0s[pre] == '(')

代码:

public int longestValidParentheses(String s) {
    int maxLen = 0;
    int[] dp = new int[s.length()]; // 默认全为 0
    
    for (int i = 1; i < s.length(); i++) {
        // 只处理右括号的情况
        if (s.charAt(i) == ')') {
            // 情况1: 形如 "()"
            if (s.charAt(i - 1) == '(') {
                dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
            } 
            // 情况2: 形如 "))"
            else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
                dp[i] = dp[i - 1] + 2;
                // 加上匹配左括号之前可能存在的有效子串长度
                if (i - dp[i - 1] - 2 >= 0) {
                    dp[i] += dp[i - dp[i - 1] - 2];
                }
            }
            // 更新最大长度
            maxLen = Math.max(maxLen, dp[i]);
        }
    }
    return maxLen;
}

posted @ 2026-04-22 11:45  狐狸胡兔  阅读(5)  评论(0)    收藏  举报