当前位置: 首页 > 知识库问答 >
问题:

打印最长的回文子串(LPS)

贾飞章
2023-03-14

我正在为自己学习DP,我可以轻松解决最长回文子串的长度,但很难真正打印最长回文子串。我检查了一个视频链接,他展示了一种获得LPS的方法,但我无法让它适用于更长的序列。考虑geeksforgeeks的例子:

S: forgeeksskeegfor

现在在我的方法中,我将填充表格的底部三角形,如下所示:

for (int i = 1; i < dp.length; ++i)
    for (int j = i-1; j >= 0; --i)
        dp[i][j] = (s[i] == s[j]) ? 2+dp[i-1][j+1] : Math.max(dp[i][j+1], dp[i-1][j])

因此,对于上述字符串,我的DP表如下所示:

      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
      f  o  r  g  e  e  k  s  s  k  e  e  g  f  o  r
 0 f  1
 1 o  1  1
 2 r  1  1  1
 3 g  1  1  1  1
 4 e  1  1  1  1  1
 5 e  2  2  2  2  2  1
 6 k  2  2  2  2  2  1  1
 7 s  2  2  2  2  2  1  1  1
 8 s  2  2  2  2  2  2  2  2  1
 9 k  4  4  4  4  4  4  4  2  1  1
10 e  6  6  6  6  6  6  4  2  1  1  1
11 e  8  8  8  8  8  6  4  2  2  2  2  1
12 g 10 10 10 10  8  6  4  2  2  2  2  1  1
13 f 12 10 10 10  8  6  4  2  2  2  2  1  1  1
14 o 12 12 10 10  8  6  4  2  2  2  2  1  1  1  1
15 r 12 12 12 10  8  6  4  2  2  2  2  1  1  1  1  1

这是视频中原始矩阵的转置,反过来,我不需要单独处理len 1,2,

12 => dp[15][0] => s[0] != s[15], now which way I go... I the video he goes on max of the next or top elements but for longer strings those might be equal. So, let's suppose I go upwards and nor 'f' neither 'r' are part of the LPS.
12 => dp[14][0] => s[0] != s[14]
12 => dp[13][0] => s[0] == s[13] => LPS: f[..........]f (At this point I go diagonally)
10 => dp[12][1] => s[1] != s[12] At this point I would start to go up as before but if I do that I won't get the LPS, so I have to go right
10 => dp[12][2] => s[2] != s[12] Still going right
10 => dp[12][3] => s[3] == s[12] => LPS: fg[........]gf
 8 => dp[11][4] => s[4] == s[11] => LPS: fge[......]efg
 6 => dp[10][5] => s[5] == s[10] => LPS: fgee[....]eefg
 4 => dp[ 9][6] => s[6] == s[ 9] => LPS: fgeek[..]keegf
 2 => dp[ 8][7] => s[7] == s[ 8] => LPS: fgeeksskeegf
 0 DONE

所以问题是,为什么我在dp[13][0]找到一个匹配项后,就把方向从向上切换到向上?如果我开始向右走,我发现我匹配,我不能继续向右走,也不能根据单元格的最大值来决定,因为它们可能相等。对于短字符串,请确保其工作原理与链接视频中的示例相同,但仅此而已。更长的字符串等于相邻单元格,那么我该走哪条路?

共有1个答案

靳举
2023-03-14

为了在DP中执行回溯,您需要记住您来自哪里。通常这意味着内存现在将增加到O(N^2),即使您可以在O(N)中完成。

我们从[12][1][12][2]而不是[11][2]的原因是,如果你在进行计算,[12][1]的值将由[12][2]确定,因为字母不相等,它是最大值。这就是我们向右转的原因——是细胞决定了这个细胞值。在所有其他情况下,这并不重要,因为这些值是相等的,所以你可以向右或向上移动。

 类似资料:
  • 我正试图从leet代码中解决一个问题。我为此写了一个方法。这在local Eclipse中工作得很好,但是当我在leetcode上提交这个解决方案时,它说超过了时间限制。 有人能给我一些建议吗?我可以在下面的代码中修改一些东西,以使它更快地工作?我也可以在这个帖子中输入字符串。 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

  • 下面的代码给出了最长的回文子序列长度。如何修改代码以获得最长的回文子串长度? 下面是一个示例调用:

  • 以下是我尝试过的,但在某些情况下失败了,但我觉得我几乎走上了正确的轨道。

  • 我的最新博客地址:我的最新博客 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 示例 2: 输入: "cbbd" 输出: "bb" 实现如下: /** * @param {string} s * @return {string} */

  • longestCommonSubsequence正在返回LCS的长度。代码运行良好。但我试图打印子序列的值。例如,它应该打印“acef”。但我的代码只打印“ae”<如何修复? 这是完整的代码https://pastebin.com/Sq4QMtxF

  • 这就是leetcode问题:给定一个字符串s,在s中找到最长的回文子字符串。您可以假定s的最大长度是1000。我的解决方案是使用一个dp表,其中dp[i][j]=以S[i]开始,以S[j]结束的最长回文子字符串的长度 我想知道为什么我的解决方案的时间限制超过了错误,不应该是O(n^2)吗?