最长重复子串(动态规划解法)
字数 1219 2025-11-18 18:26:00

最长重复子串(动态规划解法)

题目描述:
给定一个字符串s,找到最长重复子串的长度。重复子串是指在字符串中至少出现两次的连续子串,且这两个子串不能重叠(即它们的起始位置不同)。

解题过程:
这是一个经典的字符串处理问题,我们可以使用动态规划来解决。让我详细解释解决这个问题的思路和步骤。

  1. 问题分析:
  • 我们需要找到在字符串s中至少出现两次的连续子串
  • 这两个子串不能重叠(起始位置不同)
  • 目标是找到最长的这样的子串
  1. 动态规划定义:
    定义dp[i][j]表示以第i个字符结尾的子串和以第j个字符结尾的子串的最长公共后缀的长度,其中i < j。

  2. 状态转移方程:

  • 如果s[i] == s[j]:
    dp[i][j] = dp[i-1][j-1] + 1
  • 否则:
    dp[i][j] = 0
  1. 边界条件:
  • 当i = 0或j = 0时,dp[i][j] = 0(因为索引从0开始)
  1. 算法步骤:
    步骤1:初始化一个二维数组dp,大小为n×n,其中n是字符串长度
    步骤2:初始化maxLen = 0来记录最长重复子串的长度
    步骤3:遍历所有可能的i和j组合(i < j)
    步骤4:对于每个位置对(i, j):
  • 如果s[i] == s[j]:
    • 如果i == 0,dp[i][j] = 1
    • 否则,dp[i][j] = dp[i-1][j-1] + 1
  • 否则:dp[i][j] = 0
    步骤5:更新maxLen = max(maxLen, dp[i][j])
    步骤6:返回maxLen
  1. 详细示例:
    以字符串"ababc"为例:
  • s = "ababc",n = 5
  • 我们构建dp表:
i\j 0 1 2 3 4
0 0 0 1 0 0
1 0 0 0 2 0
2 0 0 0 0 3
3 0 0 0 0 0
4 0 0 0 0 0

关键计算:

  • dp[0][2]:s[0]='a'=s[2]='a',所以dp[0][2]=1
  • dp[1][3]:s[1]='b'=s[3]='b',且dp[0][2]=1,所以dp[1][3]=2
  • dp[2][4]:s[2]='a'=s[4]='a',但dp[1][3]=2,所以dp[2][4]=3

最长重复子串长度是3,对应子串"aba"和"aba"。

  1. 时间复杂度优化:
  • 时间复杂度:O(n²)
  • 空间复杂度:O(n²),可以优化到O(n)
  1. 空间优化版本:
    我们可以只保存前一行的信息,将空间复杂度从O(n²)降到O(n)。

这个解法通过动态规划巧妙地找到了最长的重复子串,核心思想是利用后缀匹配来识别重复出现的模式。

最长重复子串(动态规划解法) 题目描述: 给定一个字符串s,找到最长重复子串的长度。重复子串是指在字符串中至少出现两次的连续子串,且这两个子串不能重叠(即它们的起始位置不同)。 解题过程: 这是一个经典的字符串处理问题,我们可以使用动态规划来解决。让我详细解释解决这个问题的思路和步骤。 问题分析: 我们需要找到在字符串s中至少出现两次的连续子串 这两个子串不能重叠(起始位置不同) 目标是找到最长的这样的子串 动态规划定义: 定义dp[ i][ j]表示以第i个字符结尾的子串和以第j个字符结尾的子串的最长公共后缀的长度,其中i < j。 状态转移方程: 如果s[ i] == s[ j ]: dp[ i][ j] = dp[ i-1][ j-1 ] + 1 否则: dp[ i][ j ] = 0 边界条件: 当i = 0或j = 0时,dp[ i][ j ] = 0(因为索引从0开始) 算法步骤: 步骤1:初始化一个二维数组dp,大小为n×n,其中n是字符串长度 步骤2:初始化maxLen = 0来记录最长重复子串的长度 步骤3:遍历所有可能的i和j组合(i < j) 步骤4:对于每个位置对(i, j): 如果s[ i] == s[ j ]: 如果i == 0,dp[ i][ j ] = 1 否则,dp[ i][ j] = dp[ i-1][ j-1 ] + 1 否则:dp[ i][ j ] = 0 步骤5:更新maxLen = max(maxLen, dp[ i][ j ]) 步骤6:返回maxLen 详细示例: 以字符串"ababc"为例: s = "ababc",n = 5 我们构建dp表: i\j | 0 | 1 | 2 | 3 | 4 --- | -- | -- | -- | -- | -- 0 | 0 | 0 | 1 | 0 | 0 1 | 0 | 0 | 0 | 2 | 0 2 | 0 | 0 | 0 | 0 | 3 3 | 0 | 0 | 0 | 0 | 0 4 | 0 | 0 | 0 | 0 | 0 关键计算: dp[ 0][ 2]:s[ 0]='a'=s[ 2]='a',所以dp[ 0][ 2 ]=1 dp[ 1][ 3]:s[ 1]='b'=s[ 3]='b',且dp[ 0][ 2]=1,所以dp[ 1][ 3 ]=2 dp[ 2][ 4]:s[ 2]='a'=s[ 4]='a',但dp[ 1][ 3]=2,所以dp[ 2][ 4 ]=3 最长重复子串长度是3,对应子串"aba"和"aba"。 时间复杂度优化: 时间复杂度:O(n²) 空间复杂度:O(n²),可以优化到O(n) 空间优化版本: 我们可以只保存前一行的信息,将空间复杂度从O(n²)降到O(n)。 这个解法通过动态规划巧妙地找到了最长的重复子串,核心思想是利用后缀匹配来识别重复出现的模式。