算法一:动态规划
时间复杂度:O( n 2 n^2 n2)
状态个数:
(
n
+
1
)
n
2
\frac{(n+1)n}{2}
2(n+1)n
状态转移:4
分析
f[i][j]表示所有i~j的回文串的集合的最大值。
集合划分:
1.包含i,j两个点。包含i,j两点首先要满足
s[i] == s[j]
并且i+1~j-1也要是个回文串(否则会出现这种情况abca
显然不是回文串)。所以f[i][j] = f[i + 1][j - 1] + 2
。
2.包含i,不包含j。首先要明确f[i][j - 1]
与这种情况不完全相等,包含i,不包含j的集合是f[i][j - 1]
的子集,但由于要求最大值,所以在集合划分的时候可以有交集。
3.不包含i,包含j。同2f[i + 1][j]
。
4.i,j两点均不包含。f[i + 1][j - 1]
。
C++代码
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
vector<vector<int>> f(n, vector<int>(n));
int maxLength = 1, begin = 0;
for (int len = 1; len <= n; len++)
for (int l = 0; l + len - 1 < n; l++){
int r = l + len - 1;
if (len == 1) f[l][r] = 1;
else{
if (s[l] == s[r] && f[l + 1][r - 1] == (r - l - 1)) f[l][r] = f[l + 1][r - 1] + 2;
f[l][r] = max(f[l][r], f[l + 1][r - 1]);
f[l][r] = max(f[l][r], f[l][r - 1]);
f[l][r] = max(f[l][r], f[l + 1][r]);
if (f[l][r] > maxLength){
maxLength = f[l][r];
begin = l;
}
}
}
return s.substr(begin, maxLength);
}
};