解析:最长公共子串的变形,设有s、rs串,最长公共子串f(i,j)
上述公式是求最长公共子串的公式
如果要公共子串是回文串,设rs串是s串的reverse,还需要再加一个判定,即rs中的子串和s的子串位置一致
如 s = "abcdefdcba" 则 rs = "abcdfedcba",虽然s和rs最长公共子串是"abcd",但是不回文,因为rs中的"abcd"是由s中的"dcba"得到。
再如 s = "abbacd" rs = "dcabba" 最长公共子串为abba,满足回文,因为rs中的"abba"正是有s中的"abba"得来
判断rs中的子串是否有s的来的位置公示为:
设i为s子串最后一个字符的索引(从零开始),j为为rs子串最后一个字符的索引,sub_len为子串长度,s_len为s、rs长度,则有
i + 1 + j + 1 - sub_len = s_len
所以最长回文串设有s、rs串,其中rs是s的reverse,则g(i, j)
时间复杂度O(n^2), 动态规划部分空间复杂度可以压缩至O(1)。
C++
空间复杂度O(n^2)
class Solution {
public:
string longestPalindrome(string s)
{
string rs = s;
reverse(rs.begin(), rs.end());
int tag[1005][1005];
int max_length = -1;
int s_index = -1;
for (int i = 1; i <= s.length(); i++)
{
for (int j = 1; j <= s.length(); j++)
{
if (s[i - 1] == rs[j - 1])
{
tag[i][j] = tag[i - 1][j - 1] + 1;
if ((i + j - tag[i][j] == s.length()) && tag[i][j] > max_length)
{
max_length = tag[i][j];
s_index = i - 1;
}
}
else
{
tag[i][j] = 0;
}
}
}
string res = "";
for (int i = max_length - 1; i >= 0; i--)
{
res += s[s_index - i];
}
return res;
}
};