难度:medium
给你一个字符串 s
,找到 s
中最长的回文子串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb"
class Solution {
public:
string longestPalindrome(string s)
{
string str;
str.assign(s,0,1);
int max=0;
int num=s.size();
for(int i=1;i<num;i++)
{
int num1=one(s,i,num);
if(num1>max)
{
max=num1;
str.assign(s,i-num1,num1*2+1);
cout<<num1;
}
if(s[i]==s[i-1])
{
int num2=two(s,i-1,num);
if(num2+1>max)
{
max=num2;
str.assign(s,i-1-num2,num2*2+2);
}
}
}
return str;
}
int one(string s,int central,int num)
{
int left=central-1,right = central+1;
while(left>=0&&right<num)
{
if(s[left]!=s[right])
{
return central-left-1;
}
left--;
right++;
}
return central-left-1;
}
int two(string s1,int central,int num)
{
int left=central-1,right = central+2;
while(left>=0&&right<num)
{
if(s1[left]!=s1[right])
{
return central-left-1;
}
left--;
right++;
}
return central-left-1;
}
};
本体采用中心扩展算法
找出其中的状态转移链:
边界情况即为子串长度为 11 或 22 的情况。我们枚举每一种边界情况,并从对应的子串开始不断地向两边扩展。如果两边的字母相同,我们就可以继续扩展,例如从 P(i+1,j-1)P(i+1,j−1) 扩展到 P(i,j)P(i,j);如果两边的字母不同,我们就可以停止扩展,因为在这之后的子串都不能是回文串了。
应该可以发现,「边界情况」对应的子串实际上就是我们「扩展」出的回文串的「回文中心」。方法二的本质即为:我们枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。我们对所有的长度求出最大值,即可得到最终的答案。
我们需要计算中心字串为双字符的情形