回文就是顺序和逆序一样的字符串。
试了两种方法
1.中心扩展算法
一个长度为n的字符串,中心个数为2n-1
扩展方式:
当中心点左右的字符相同,就扩展回文的边界left和right(left–,right++),直到左右边界的字符不相同。这样就得到了从这一中心点能扩展到的最长的回文子串。
从头到位遍历所有中心点,记录最长的回文子串~解决问题
代码:
char* longestPalindrome(char* s) {
int len = strlen(s);
if(len <= 1)
return s;
int start = 0,end = 0;
for(int i = 0; i < len; i++)
{
int len1 = expandlist(s,i,i);
int len2 = expandlist(s,i,i+1);
int maxlen = max(len1,len2);
if(maxlen > end-start+1) //更新回文子串
{
start = i - (maxlen - 1)/2;
end = i + maxlen/2;
}
}
char *r=(char*)malloc(sizeof(int)* ((end-start+2))); //动态申请数组
strncpy(r,s+start,end-start+1);
r[end-start+1] = '\0';
return r;
}
int expandlist(char* s, int i, int j) //获取最长回文子串长度函数
{
int len = strlen(s);
int left = i,right = j;
while(left>=0&&right<len&&s[left]==s[right])
{
left--;
right++;
}
return right-left-1;
}
int max(int a, int b)
{
return a>b?a:b;
}
2.动态规划
创建一个二维数组a[][],a[i][j]用来记录第i个字符到第j个字符的子串是否为回文。
逻辑:
j-i=0,单个字符,肯定是回文
j-i=1,两个字符,如果两个字符相同则是回文
j-i>1,多个字符,如果第i个和第j个字符相同 && 第i+1个字符到第j-1个字符形成的子串是回文,则是回文
代码:
char* longestPalindrome(char* s) {
int len = strlen(s);
if(len <= 1)
return s;
int **a; //用二级指针动态申请二维数组
a=(int**)malloc(sizeof(int*)*len);
for(int i=0;i<len;i++)
a[i]=(int*)malloc(sizeof(int)*len);
int left = 0;
int right = 0;
for(int i=len-2;i>=0;i--)
{
a[i][i] = 1;
for(int j = i+1;j<len;j++)
{
if(s[i]==s[j]&&(j-i<3||a[i+1][j-1]==1))
{
a[i][j]=1;
}
if(j-i>right-left && a[i][j] == 1)
{
left = i;
right = j;
}
}
}
char *r=(char*)malloc(sizeof(int)* ((right-left+2)));
strncpy(r,s+left,right-left+1);
r[right-left+1] = '\0';
return r;
}