最长公共子序列的变种:带字符出现次数限制的最长公共子序列(进阶版:限制某些字符必须连续出现k次)
字数 1196 2025-11-09 10:55:00

最长公共子序列的变种:带字符出现次数限制的最长公共子序列(进阶版:限制某些字符必须连续出现k次)

题目描述:
给定两个字符串s和t,以及一个字符c和整数k。要求找到s和t的最长公共子序列,且该子序列中字符c必须连续出现至少k次。如果不存在这样的子序列,返回0。

解题过程:
这个问题是LCS的变种,增加了对特定字符连续出现次数的限制。我们需要在动态规划状态中额外记录关于字符c连续出现次数的信息。

  1. 状态定义:
    定义dp[i][j][x][y],其中:
  • i: 在s中处理到第i个字符(1-indexed)
  • j: 在t中处理到第j个字符(1-indexed)
  • x: 当前公共子序列末尾字符c的连续出现次数(0表示当前字符不是c)
  • y: 表示当前是否已经开始c的连续序列(0未开始,1已开始)
  1. 状态转移:
    考虑四种情况:

情况1:不选择s[i]和t[j]
dp[i][j][x][y] = max(dp[i][j][x][y], dp[i-1][j-1][x][y])

情况2:选择s[i]和t[j],且s[i] == t[j]

  • 如果s[i] == c:
    • 如果x > 0(前一个字符也是c):dp[i][j][x+1][1] = max(dp[i][j][x+1][1], dp[i-1][j-1][x][y] + 1)
    • 如果x == 0(前一个字符不是c):dp[i][j][1][1] = max(dp[i][j][1][1], dp[i-1][j-1][x][y] + 1)
  • 如果s[i] != c:
    dp[i][j][0][y] = max(dp[i][j][0][y], dp[i-1][j-1][x][y] + 1)

情况3:不选择s[i],选择t[j]
dp[i][j][x][y] = max(dp[i][j][x][y], dp[i-1][j][x][y])

情况4:选择s[i],不选择t[j]
dp[i][j][x][y] = max(dp[i][j][x][y], dp[i][j-1][x][y])

  1. 初始化:
  • dp[0][0][0][0] = 0
  • 其他位置初始化为负无穷(表示不可达状态)
  1. 结果提取:
    最终结果是所有满足x >= k的dp[n][m][x][1]中的最大值(n和m分别是s和t的长度)

  2. 优化:
    由于状态空间较大,可以考虑使用滚动数组优化空间复杂度。

这个算法的时间复杂度是O(n×m×k),其中n和m是字符串长度,k是要求的连续出现次数。通过记录字符c的连续出现情况,我们能够在寻找LCS的同时满足对特定字符连续出现次数的限制要求。

最长公共子序列的变种:带字符出现次数限制的最长公共子序列(进阶版:限制某些字符必须连续出现k次) 题目描述: 给定两个字符串s和t,以及一个字符c和整数k。要求找到s和t的最长公共子序列,且该子序列中字符c必须连续出现至少k次。如果不存在这样的子序列,返回0。 解题过程: 这个问题是LCS的变种,增加了对特定字符连续出现次数的限制。我们需要在动态规划状态中额外记录关于字符c连续出现次数的信息。 状态定义: 定义dp[ i][ j][ x][ y ],其中: i: 在s中处理到第i个字符(1-indexed) j: 在t中处理到第j个字符(1-indexed) x: 当前公共子序列末尾字符c的连续出现次数(0表示当前字符不是c) y: 表示当前是否已经开始c的连续序列(0未开始,1已开始) 状态转移: 考虑四种情况: 情况1:不选择s[ i]和t[ j ] dp[ i][ j][ x][ y] = max(dp[ i][ j][ x][ y], dp[ i-1][ j-1][ x][ y ]) 情况2:选择s[ i]和t[ j],且s[ i] == t[ j ] 如果s[ i ] == c: 如果x > 0(前一个字符也是c):dp[ i][ j][ x+1][ 1] = max(dp[ i][ j][ x+1][ 1], dp[ i-1][ j-1][ x][ y ] + 1) 如果x == 0(前一个字符不是c):dp[ i][ j][ 1][ 1] = max(dp[ i][ j][ 1][ 1], dp[ i-1][ j-1][ x][ y ] + 1) 如果s[ i] != c: dp[ i][ j][ 0][ y] = max(dp[ i][ j][ 0][ y], dp[ i-1][ j-1][ x][ y ] + 1) 情况3:不选择s[ i],选择t[ j ] dp[ i][ j][ x][ y] = max(dp[ i][ j][ x][ y], dp[ i-1][ j][ x][ y ]) 情况4:选择s[ i],不选择t[ j ] dp[ i][ j][ x][ y] = max(dp[ i][ j][ x][ y], dp[ i][ j-1][ x][ y ]) 初始化: dp[ 0][ 0][ 0][ 0 ] = 0 其他位置初始化为负无穷(表示不可达状态) 结果提取: 最终结果是所有满足x >= k的dp[ n][ m][ x][ 1 ]中的最大值(n和m分别是s和t的长度) 优化: 由于状态空间较大,可以考虑使用滚动数组优化空间复杂度。 这个算法的时间复杂度是O(n×m×k),其中n和m是字符串长度,k是要求的连续出现次数。通过记录字符c的连续出现情况,我们能够在寻找LCS的同时满足对特定字符连续出现次数的限制要求。