题目:给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
有两种算法,一种是中心扩散算法,通过遍历每一字符,以当前字符为中心左右扩散进行对比,较为简单再次不做详细描述。
本文章主要介绍动态规划的方法。
我们很容易知道的是,当左右两端的字符相同时,当前字串是否为回文字串依赖于中间的子子串是否为回文字串,以此类推我们可以得出状态转移方程:
而且单个字符就是最短得回文子串,根据此可以初始化table。
class Solution {
public:
string longestPalindrome(string s) {
int len = s.length();
if(len<2){
return s;
}
int maxlen = 1;
int begin = 0;
vector<vector<bool>> dp(len, vector<bool>(len));
//初始化,每一个单词是最短回文
for(int i= 0;i<len;i++){
dp[i][i]=true;
}
//遍历子串长度,字串长度的范围从2到全部
for(int L= 2;L<=len;L++){
//定位子串左坐标
for(int i=0;i<len;i++){
//定位字串右坐标
int j = i+L-1;
//超出字符串范围
if(j>=len){
break;
}
//判断左右字符是否相同
if(s[i]!=s[j]){
//不相同则不是字串
dp[i][j]=false;
}
else{
//左右字符中间没有或只有一个字符
if(j-i<3){
dp[i][j]=true;
}else{
//当前左右字符内有字串,是否为回文依赖于中间的子串
dp[i][j]=dp[i+1][j-1];
}
}
//判断当前回文子串是否为最长回文子串
if(dp[i][j]==true&&j-i+1>maxlen){
maxlen=j-i+1;
begin = i;
}
}
}
return s.substr(begin,maxlen);
}
};