最长括号匹配子序列问题
字数 1201 2025-11-27 15:06:23

最长括号匹配子序列问题

题目描述:
给定一个只包含 '(' 和 ')' 的字符串 s,找出最长的有效括号子序列的长度。有效括号子序列定义为:该子序列中每个左括号 '(' 都有一个对应的右括号 ')' 正确匹配,并且匹配关系是合法的。

解题过程:

  1. 问题分析:
  • 我们需要找到一个子序列(不一定连续),使其形成有效的括号匹配
  • 与最长有效括号子串不同,子序列不要求字符连续
  • 例如:s = "()())" 的最长有效括号子序列长度为4("()()")
  1. 动态规划定义:
    定义 dp[i][j] 表示字符串 s 在区间 [i, j] 内的最长有效括号子序列长度。

  2. 状态转移方程:

  • 基本情况:当 i > j 时,dp[i][j] = 0(空区间)

  • 当 i = j 时,dp[i][j] = 0(单个字符无法形成匹配)

  • 对于区间 [i, j]:
    a) 如果 s[j] 不参与匹配:dp[i][j] = dp[i][j-1]

    b) 如果 s[j] 参与匹配,需要找到与之匹配的左括号:
    遍历 k 从 i 到 j-1:
    如果 s[k] == '(' 且 s[j] == ')',那么:
    dp[i][j] = max(dp[i][j], dp[i][k-1] + dp[k+1][j-1] + 2)

  1. 计算顺序:
    由于需要小区间的结果来计算大区间,我们按区间长度从小到大计算:
  • 先计算长度为1的区间
  • 然后计算长度为2的区间
  • 依次递增,直到整个字符串
  1. 具体步骤示例:
    以 s = "()())" 为例:

初始化:

  • 所有长度为1的区间:dp[i][i] = 0

  • 长度为2的区间:
    dp[0][1]:s[0]='(', s[1]=')' → 匹配,长度为2
    dp[1][2]:s[1]=')', s[2]='(' → 不匹配,长度为0
    dp[2][3]:s[2]='(', s[3]=')' → 匹配,长度为2
    dp[3][4]:s[3]=')', s[4]=')' → 不匹配,长度为0

  • 长度为3的区间:
    dp[0][2]:考虑s[2]是否匹配
    与s[0]匹配:dp[1][1] + 2 = 0 + 2 = 2
    与s[1]不匹配
    最终:max(dp[0][1], 2) = 2

  • 长度为4的区间:
    dp[1][4]:考虑s[4]是否匹配
    与s[1]匹配:dp[2][3] + 2 = 2 + 2 = 4
    最终结果为4

  1. 算法实现要点:
  • 时间复杂度:O(n³)(可通过优化到O(n²))
  • 空间复杂度:O(n²)
  • 最终结果:dp[0][n-1] 即为整个字符串的最长有效括号子序列长度
  1. 优化思路:
    可以记录每个位置可能的最优匹配,将时间复杂度优化到O(n²),但基本思路保持不变。
最长括号匹配子序列问题 题目描述: 给定一个只包含 '(' 和 ')' 的字符串 s,找出最长的有效括号子序列的长度。有效括号子序列定义为:该子序列中每个左括号 '(' 都有一个对应的右括号 ')' 正确匹配,并且匹配关系是合法的。 解题过程: 问题分析: 我们需要找到一个子序列(不一定连续),使其形成有效的括号匹配 与最长有效括号子串不同,子序列不要求字符连续 例如:s = "()())" 的最长有效括号子序列长度为4("()()") 动态规划定义: 定义 dp[ i][ j] 表示字符串 s 在区间 [ i, j ] 内的最长有效括号子序列长度。 状态转移方程: 基本情况:当 i > j 时,dp[ i][ j ] = 0(空区间) 当 i = j 时,dp[ i][ j ] = 0(单个字符无法形成匹配) 对于区间 [ i, j ]: a) 如果 s[ j] 不参与匹配:dp[ i][ j] = dp[ i][ j-1 ] b) 如果 s[ j ] 参与匹配,需要找到与之匹配的左括号: 遍历 k 从 i 到 j-1: 如果 s[ k] == '(' 且 s[ j ] == ')',那么: dp[ i][ j] = max(dp[ i][ j], dp[ i][ k-1] + dp[ k+1][ j-1 ] + 2) 计算顺序: 由于需要小区间的结果来计算大区间,我们按区间长度从小到大计算: 先计算长度为1的区间 然后计算长度为2的区间 依次递增,直到整个字符串 具体步骤示例: 以 s = "()())" 为例: 初始化: 所有长度为1的区间:dp[ i][ i ] = 0 长度为2的区间: dp[ 0][ 1]:s[ 0]='(', s[ 1 ]=')' → 匹配,长度为2 dp[ 1][ 2]:s[ 1]=')', s[ 2 ]='(' → 不匹配,长度为0 dp[ 2][ 3]:s[ 2]='(', s[ 3 ]=')' → 匹配,长度为2 dp[ 3][ 4]:s[ 3]=')', s[ 4 ]=')' → 不匹配,长度为0 长度为3的区间: dp[ 0][ 2]:考虑s[ 2 ]是否匹配 与s[ 0]匹配:dp[ 1][ 1 ] + 2 = 0 + 2 = 2 与s[ 1 ]不匹配 最终:max(dp[ 0][ 1 ], 2) = 2 长度为4的区间: dp[ 1][ 4]:考虑s[ 4 ]是否匹配 与s[ 1]匹配:dp[ 2][ 3 ] + 2 = 2 + 2 = 4 最终结果为4 算法实现要点: 时间复杂度:O(n³)(可通过优化到O(n²)) 空间复杂度:O(n²) 最终结果:dp[ 0][ n-1 ] 即为整个字符串的最长有效括号子序列长度 优化思路: 可以记录每个位置可能的最优匹配,将时间复杂度优化到O(n²),但基本思路保持不变。