题目链接:LeetCode5
思路:除了马拉车算法和中心扩散法外的一种通用高效的算法,核心思路是优化暴力中查子串是否为回文串的二维DP
class Solution {
public:
string longestPalindrome(string str) {
int len = str.size();
bool dp[1005][1005]; //dp[i][j]表示第i个到第j个的子串是否为回文串
memset(dp, false, sizeof(dp));
for (int i = 1; i <= len; i++) {
dp[i][i] = true; //单个字符显然是回文串
if (i-1>0 && str[i-1] == str[i-2]) //相邻相等的情况
dp[i-1][i] = true;
}
//如果str(i+1...j-1)是回文的话,并且str[i]==str[j],显然str(i...j)也是回文
//整个问题的子问题就找到了,不难发现每次的状态都是从上上轮转移过来的
for (int j = 3; j <= len; j++)
for (int i = 1; i+j-1 <= len; i++)
if (dp[i+1][i+j-2] && str[i-1] == str[i+j-2])
dp[i][i+j-1] = true;
//这样爆搜就能够降到O(n^2),因为判断某个串是否为回文串就能O(1)查出
int start = 1, length = 1;
for (int i = 1; i <= len; i++)
for (int j = i+1; j <= len; j++)
if (dp[i][j] && length < j-i+1)
start=i, length=j-i+1;
return str.substr(start-1, length);
}
};