题目:给你一个字符串 s
,找到 s
中最长的回文子串。
示例输入:
示例1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例2:
输入:s = "cbbd"
输出:"bb"
提示:
-
1 <= s.length <= 1000
-
s
仅由数字和英文字母组成
题解:
算法1:动态规划
构造dp数组,其中dp[i][j]用来表示字符串下标从i到j的子串是否为回文字符串,1表示是,0表示否,dp[i][i]肯定为1,那么从d[i][i]开始扩展,只要d[i][j]为1,并且s[i-1]==s[j+1]那么就可以得到d[i-1][j+1]为1。动态规划从就是通过这样的思想来寻找最长的回文子串。
算法2:中心扩散
通过循环遍历的方式,当前下标表示回文子串的中心起始点,然后进行中心扩散,同时扩展上边界和下边界找到以当前的字串为中心的最长回文子串;完成后更新下标为中心的上边界。
代码:
算法1
class Solution {
public:
string longestPalindrome(string s) {
if(s.size()<2)
{
return s;
}
int dp[1001][1001];
int maxlen=1,start=0,end=0;
for(int i=0;i<s.size();i++)
{
dp[i][i]=1;
}
for(int len=2;len<=s.size();len++)//字串长度从2开始
{
for(int l=0;l<s.size();l++)//字串左边界
{
int r=l+len-1;//字串右边界
if(r>=s.size())//判断边界情况
{
break;
}
if(s[l]!=s[r])
{
dp[l][r]=0;
}
else
{
if(r-l<3)
{
dp[l][r]=1;
}
else
{
dp[l][r]=dp[l+1][r-1];
}
}
if(r-l+1>maxlen&&dp[l][r]==1)//判断是否大于最大长度
{
maxlen=r-l+1;
start=l;
end=r;
}
}
}
return s.substr(start,maxlen);
}
};
算法2
class Solution {
public:
string longestPalindrome(string s) {
if(s.size()<=0)
{
return "";
}
int start=0,end=0;
for(int i=0;i<s.size();i++)
{
i=find(s,i,start,end);
}
return s.substr(start,end-start+1);
}
int find(string s,int low,int& start,int& end)
{
int high=low;
while(high<s.size()-1&&s[high+1]==s[low])//找到中心上边界
{
high++;
}
int res=high;
while(low>0&&high<s.size()-1&&s[low-1]==s[high+1])//中心扩展
{
high++;
low--;
}
if(high-low>end-start)//更新边界情况,记录最大长度
{
start=low;
end=high;
}
return res;
}
};