打印最长回文子串(LPS)

时间:2020-01-03 11:07:39

标签: algorithm dynamic-programming

我正在为自己学习DP,我可以轻松解决最长回文子串的长度,但是很难打印最长回文子串。我查看了一个视频LINK,其中他展示了一种获取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,> = 3长度的palindrom子序列。无论哪种方法,问题都与我追求的方法相同。因此,最长回文子序列的长度为dp [15] [0]:= 12,这是正确的。问题是追溯...

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 个答案:

答案 0 :(得分:0)

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

我们从[12][1][12][2]而不是[11][2]的原因是,如果您正在进行计算-[12][1]的值将由{{ 1}},因为字母不相等且为最大值。这就是我们要正确的原因-决定此单元格值的是单元格。在所有其他情况下,因为值相等,所以实际上并没有多大关系,因此您可以向上或向右移动。

相关问题