题目描述
给你一个字符串 s,找到 s 中最长的回文子串。
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
题目链接:力扣5–最长回文子串
思路分析及答案
除去单个字符一定是回文串,剩下分成两种子串。
- 一种是长度为2或者3的子串,这种只需要判断首尾字符是否相等,因为长度为2的子串首尾相等则肯定是回文串,不相等就不是。长度为3的子串若首尾相等则一定也是回文子串,因为中间只有一个字符。
- 另一种是长度大于3的子串,若首尾元素s[ i ]和s[ j ]不同,则该子串肯定不是回文串;若首尾元素相同,则按照动规思想,只需要看去掉当前首尾元素的串(即起点为i+1,结束为j-1)是不是回文串,依次类推。
代码:
class Solution {
public:
string longestPalindrome(string s) {
int n=s.size();
if(n==1)
{
return s;
}
//1.定义状态--dp[i][j]代表从s中i到j的子串是否是回文串
vector<vector<int>> dp(n,vector<int>(n));
//初始化,单个字符肯定都是回文串
for(int i=0;i<n;i++)
{
dp[i][i]=true;
}
int begin=0;//最终回文符串的起点
int len=1;//最终回文串的长度,注意最小应该是1,比如ac,结果为a
for(int j=1;j<n;j++)
{
for(int i=0;i<j;i++)
{
if(s[i]!=s[j])//i位置与j位置字符不相等
{
dp[i][j]=false;
}
else//i位置与j位置字符相等
{
if(j-i+1<=3)//如果子串字符长度为2或3
{
dp[i][j]=true;
}
else
{
dp[i][j]=dp[i+1][j-1];//2.状态方程
}
}
//找到dp[i][j],起始位置为i,结束为j的子串为回文串
if((dp[i][j])&&(j-i+1>len))//每次保留最长的
{
begin=i;
len=j-i+1;
}
}
}
return s.substr(begin,len);//两个参数 起始位置和截取长度
}
};