我正在为自己学习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]找到一个匹配项后,就把方向从向上切换到向上?如果我开始向右走,我发现我匹配,我不能继续向右走,也不能根据单元格的最大值来决定,因为它们可能相等。对于短字符串,请确保其工作原理与链接视频中的示例相同,但仅此而已。更长的字符串等于相邻单元格,那么我该走哪条路?
为了在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)吗?