我正在为自己学习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]找到匹配项后为什么将方向从向上切换到正确?如果我开始向右走,我发现我匹配,那么我将无法继续向右走,也无法基于单元格的最大值来决定,因为它们可能相等。对于短字符串,请确保它可以像链接的视频中的示例一样工作,但仅此而已。较长的字符串等于相邻的单元格,那我应该走哪条路?
答案 0 :(得分:0)
为了在DP中执行回溯,您需要记住您的来源。通常,这意味着即使您可以在O(N ^ 2)
中完成操作,内存现在也会增加到O(N)
。
我们从[12][1]
到[12][2]
而不是[11][2]
的原因是,如果您正在进行计算-[12][1]
的值将由{{ 1}},因为字母不相等且为最大值。这就是我们要正确的原因-决定此单元格值的是单元格。在所有其他情况下,因为值相等,所以实际上并没有多大关系,因此您可以向上或向右移动。