分析:定义二维数组dp[i,j]用以表示Si…Sj是回文(true)或不是回文(false)
- 定义dp数组全为false;
- 第一次循环设置单个字符为回文子串 dp[i][i]=true;
- 第二次循环判断相邻两个字符dp[i][i+1]是否为回文,若是则将回文子串的起始位置设为i,长度设为2;
- 第三次循环判断长度len为3到s.length()长度的子串是否为回文,j=i+len-1,dp[i][j] = (dp[i+1][j-1] && Si ==Sj),若成立修改回文串的长度,若新的回文串长度大于原始长度,则修改回文子串的起始位置。
DP法的思路就是,首先判断单个字符和两个相邻字符是否回文,然后检测连续三个字符是否回文,然后四个直到整个字符串是否为回文。
#include <iostream>
#include <string>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
int n = s.length();
int beg=0, maxlen=1;
int i, j;
if(n == 1)
return s;
//定义动态规划数组
bool dp[n][n];
for(i=0; i<n; i++) //当i==j 时,只有一个字符的字符串; 当 i > j 认为是空串,也是回文
for(j=0; j<n; j++)
{
if(i >= j)
dp[i][j] = true;
else
dp[i][j] = false;
}
for(i=0; i<n-1; i++)
{
if(s[i] == s[i+1]) //2个字符为回文串
{
dp[i][i+1] = true;
beg = i;
maxlen = 2;
}
}
for(int len=3; len<=n; len++)
for(i=0; i<n-len+1; i++)
{
j = i+len-1;
if(s[i] == s[j] && dp[i+1][j-1])
{
dp[i][j] = true;
if(maxlen < len)
beg = i;
maxlen = len;
}
}
return s.substr(beg, maxlen);
}
};
int main()
{
Solution S;
string tar="babab";
cout<<S.longestPalindrome(tar)<<endl;
return 0;
}