第一次:
void checkstr(char* x, int y, int z, int* start, int* max)
{
int i = y, j = z;
int length = 0;
while(i>=0 && j<= strlen(x)-1 && (x[i] == x[j]))
{
i--;
j++;
}
length = j-i-1;
if(length > *max)
{
*max = length;
*start = i+1;
}
}
char* longestPalindrome(char* s) {
int begin = 0, max = 1;
// int L = strlen(s);
if(strlen(s)<=1)
{
return s;
}
if(strlen(s)>1000)
{
return NULL;
}
for(int i=0; i<strlen(s)-1; i++)
{
//奇字符串
checkstr(s, i, i, &begin, &max);
//偶数
checkstr(s, i, i+1, &begin, &max);
}
char* result = (char*)malloc(sizeof(char)*(max+1));
memcpy(result, &s[begin], sizeof(char)*max);
result[max] = '\0';
return result;
}
以上时间会超过,在上面基础上优化后时间可以接受,优化方式是,不需要每次都计算s字符串的大小
void checkstr(char* x, int y, int z, int* start, int* max, int l)
{
int i = y, j = z;
int length = 0;
while(i>=0 && j<= l-1 && (x[i] == x[j]))
{
i--;
j++;
}
length = j-i-1;
if(length > *max)
{
*max = length;
*start = i+1;
}
}
char* longestPalindrome(char* s) {
int begin = 0, max = 1;
int L = strlen(s);
if(L<=1)
{
return s;
}
if(L>1000)
{
return NULL;
}
for(int i=0; i<strlen(s)-1; i++)
{
//奇字符串
checkstr(s, i, i, &begin, &max, L);
//偶数
checkstr(s, i, i+1, &begin, &max, L);
}
char* result = (char*)malloc(sizeof(char)*(max+1));
memcpy(result, &s[begin], sizeof(char)*max);
result[max] = '\0';
return result;
}
上述用到的方法是以一个点为中心,分为偶数字符串和奇数字符串两种情况,分别向左右两边扩展,寻找回文;时间复杂度是(O(n^2)). 另外可以根据
i+max/2 <strlen(s)进行再次优化
下面再介绍
马拉车算法 Manacher Algorithm计算最长回文长度
int longestPalindrome(char* s)
{
int length = strlen(s);
char p[2*length+2];
int L[2*length+1];
char* result;
int i=0,j=0;
int po=1,p_max=2,ans=2;
for(i=0; i<length; i++)
{
p[2*i] = '#';
p[2*i+1] = s[i];
}
p[2*length]='#';
p[2*length+1]='\0';
memset(&L,0,sizeof(int)*(2*length+1));
L[0]=0;
L[1]=2;
for(j=2;j<=2*length;j++)
{
if(j<p_max)
{
L[j] = p_max-j+1<L[2*po-j]?p_max-j+1:L[2*po-j];
}
else
{
L[j] = 1;
}
while((j-L[j]+1>=0)&&(j+L[j]-1<=2*length)&&(p[j-L[j]+1]==p[j+L[j]-1]))
{
L[j]++;
}
if(L[j]>p_max-po+1)//若新计算的回文串右端点位置大于mx,要更新po和mx的值
{
p_max=L[j]+j-1;
po=j;
}
ans=ans>L[j]? ans:L[j];
}
return ans-1;
}