线性动态规划:最长有效括号匹配子串的变种——允许最多k次失配的最长有效括号子串(进阶版:失配位置可修复)
字数 891 2025-11-04 08:32:42

线性动态规划:最长有效括号匹配子串的变种——允许最多k次失配的最长有效括号子串(进阶版:失配位置可修复)

题目描述:
给定一个只包含'('和')'的字符串s和一个非负整数k,要求找到最长的子串,使得这个子串可以通过最多k次字符修改(将'('改为')'或将')'改为'(')变成一个完全有效的括号字符串。

解题过程:

  1. 问题分析:
  • 这是一个带容错机制的有效括号匹配问题
  • 传统有效括号匹配要求左右括号严格匹配,这里允许最多k次修改
  • 修改操作可以理解为"修复"不匹配的括号
  1. 关键观察:
  • 我们需要同时跟踪括号的平衡度和已使用的修改次数
  • 定义dp[i][j][b]表示考虑前i个字符,使用了j次修改,当前平衡度为b时的最长有效子串长度
  • 但三维DP复杂度较高,需要优化
  1. 优化思路:
  • 使用二维DP:dp[i][j]表示以第i个字符结尾,使用了j次修改时的最大平衡度
  • 平衡度表示未匹配的'('数量,有效时平衡度应为0
  • 同时记录每个状态的最长有效长度
  1. 状态定义:
  • 定义两个二维数组:
    • balance[i][j]:以i结尾,使用j次修改时的最大平衡度
    • maxLen[i][j]:以i结尾,使用j次修改时的最长有效长度
  1. 状态转移:
    对于每个位置i和修改次数j(0 ≤ j ≤ k):
  • 如果s[i] == '(':
    • 不修改:平衡度+1,长度+1
    • 修改为')':平衡度-1,长度+1,使用次数+1
  • 如果s[i] == ')':
    • 不修改:平衡度-1,长度+1
    • 修改为'(':平衡度+1,长度+1,使用次数+1

平衡度约束:平衡度不能为负,如果为负说明无效

  1. 初始化:
  • balance[0][0] = 0, maxLen[0][0] = 0
  • 其他初始为-∞(无效状态)
  1. 算法步骤:
初始化所有balance为-∞,maxLen为0
对于i从0到n-1:
  对于j从0到k:
    如果balance[i][j]有效:
      # 处理当前字符
      ch = s[i]
      
      # 情况1:不修改当前字符
      if ch == '(':
        new_balance = balance[i][j] + 1
        if new_balance >= 0:  # 平衡度有效
          更新balance[i+1][j]和maxLen[i+1][j]
      else:  # ch == ')'
        new_balance = balance[i][j] - 1
        if new_balance >= 0:
          更新balance[i+1][j]和maxLen[i+1][j]
      
      # 情况2:修改当前字符(如果j < k)
      if j < k:
        if ch == '(':
          new_balance = balance[i][j] - 1  # 改为')'
          if new_balance >= 0:
            更新balance[i+1][j+1]和maxLen[i+1][j+1]
        else:  # ch == ')'
          new_balance = balance[i][j] + 1  # 改为'('
          if new_balance >= 0:
            更新balance[i+1][j+1]和maxLen[i+1][j+1]

记录所有平衡度为0的状态中的最大maxLen值
  1. 复杂度分析:
  • 时间复杂度:O(n×k),n为字符串长度
  • 空间复杂度:O(n×k),可优化到O(k)
  1. 边界情况处理:
  • 空字符串:返回0
  • k=0时退化为标准的最长有效括号子串问题
  • 平衡度必须始终非负

这个算法通过动态规划同时跟踪括号平衡度和修改次数,找到了在有限修改次数下的最长有效括号子串。

线性动态规划:最长有效括号匹配子串的变种——允许最多k次失配的最长有效括号子串(进阶版:失配位置可修复) 题目描述: 给定一个只包含'('和')'的字符串s和一个非负整数k,要求找到最长的子串,使得这个子串可以通过最多k次字符修改(将'('改为')'或将')'改为'(')变成一个完全有效的括号字符串。 解题过程: 问题分析: 这是一个带容错机制的有效括号匹配问题 传统有效括号匹配要求左右括号严格匹配,这里允许最多k次修改 修改操作可以理解为"修复"不匹配的括号 关键观察: 我们需要同时跟踪括号的平衡度和已使用的修改次数 定义dp[ i][ j][ b ]表示考虑前i个字符,使用了j次修改,当前平衡度为b时的最长有效子串长度 但三维DP复杂度较高,需要优化 优化思路: 使用二维DP:dp[ i][ j ]表示以第i个字符结尾,使用了j次修改时的最大平衡度 平衡度表示未匹配的'('数量,有效时平衡度应为0 同时记录每个状态的最长有效长度 状态定义: 定义两个二维数组: balance[ i][ j ]:以i结尾,使用j次修改时的最大平衡度 maxLen[ i][ j ]:以i结尾,使用j次修改时的最长有效长度 状态转移: 对于每个位置i和修改次数j(0 ≤ j ≤ k): 如果s[ i ] == '(': 不修改:平衡度+1,长度+1 修改为')':平衡度-1,长度+1,使用次数+1 如果s[ i ] == ')': 不修改:平衡度-1,长度+1 修改为'(':平衡度+1,长度+1,使用次数+1 平衡度约束:平衡度不能为负,如果为负说明无效 初始化: balance[ 0][ 0] = 0, maxLen[ 0][ 0 ] = 0 其他初始为-∞(无效状态) 算法步骤: 复杂度分析: 时间复杂度:O(n×k),n为字符串长度 空间复杂度:O(n×k),可优化到O(k) 边界情况处理: 空字符串:返回0 k=0时退化为标准的最长有效括号子串问题 平衡度必须始终非负 这个算法通过动态规划同时跟踪括号平衡度和修改次数,找到了在有限修改次数下的最长有效括号子串。