题目描述
给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
思路
dp[i][j]表述的意思是字符串s从下标i到下边j的字符串是否为回文字符串,易知若s[i]等于s[j]且dp[i+1][j-1],dp[i][j]也为真。
以此为依据,遍历的内容其实是字符串长度,因为长度为l的字符串是否为回文串是由某一个长度为l-2的字符串和首尾字符决定的;maxstart表示最长回文串的首字符下标,maxlen表示最长回文串的长度,这两个变量用来最后截取字符串,而也因为l是从小到大遍历的,最后停留的位置即是最长的位置。
边界:当长度为1时,所有从i到i的字符串(即其本身)都是回文的,所以dp[i][i]都为true;当长度为2时,只有连续两个字符相同时,也就是从i到i+1的字符串才是回文的,此时dp[i][i+1]都是true,不过这时也要更新maxstart和maxlen。
代码
class Solution {
public:
string longestPalindrome(string s) {
string res = "";
int n = s.size();
int maxstart = 0;
int maxlen = 1;
vector<vector<bool>> dp(n,vector<bool>(n,false));
for(int i=0;i<n;i++)
dp[i][i] = true;
for(int i=0;i<n-1;i++){
if(s[i] == s[i+1]){
dp[i][i+1] = true;
maxstart = i;
maxlen = 2;
}
}
for(int l=3;l<=n;l++){
for(int i=0;i+l-1<n;i++){
int j=i+l-1;
if(s[i] == s[j] && dp[i+1][j-1]){
dp[i][j] = true;
maxstart = i;
maxlen = l;
}
}
}
return s.substr(maxstart,maxlen);
}
};