给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:
输入: "babad" 输出: "bab" 注意: "aba"也是一个有效答案。
示例 2:
输入: "cbbd" 输出: "bb"
思路:将字符串中每一个元素作为中心算出其最大的回文字串的长度,最后得出整个字符串中最长回文字串的中心位置和长度。
关键:有两种情况:一、回文字串长度为奇数。二、回文字串长度为偶数。当为情况一时为理想情况,只要向左向右比较即可,但是情况二就不好处理,所以可以将所有情况转化成奇数情况。(Mancher算法)
假设有str="babad",我们创建一个大小为2*strlen(str)+2,长度的数组,并将每个元素前面和最后添加一个特殊字符“#”:
s=“#b#a#b#a#d#”;这样我们就将情况二转换成情况一。
然后再创建一个数组P来记录s中每个元素最大回文字串的长度。
以上述为例数组P为{1,2,1,4,1,4,1,2,1,2,1}
最后找到P中的最大值4(第一个最大值就行)并记录当前的索引4,因为回文字串是对称的且”#“的个数一定比原始元素的个数多1,所以我们的答案的长度为max-1;
代码如下:
char* longestPalindrome(char* s) {
int len=strlen(s);
char *str=(char*)malloc(sizeof(char)*(2*len+2));
int p[2*len+1];
int i,j=1,max=0,max_index;
str[0]='#';
for(i=0;i<len;i++)
{
str[j++]=s[i];
str[j++]='#';
}
for(i=0;i<2*len+1;i++)
{
p[i]=0;
int j=i,tmp=i;
while(j<2*len+1&&tmp>=0&&str[tmp]==str[j])
{
p[i]++;
tmp--;
j++;
}
}
for(i=0;i<2*len+1;i++)
{
if(max<p[i])
{
max=p[i];
max_index=i;
}
}
char *answer=(char *)malloc(sizeof(char)*max);
i=0,j=0;
while(i<max-1)
{
if(str[max_index-max+1+j]!='#')
{
answer[i++]=str[max_index-max+1+j];
}
j++;
}
return answer;
}