给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
char* longestPalindrome(char* s)
{
//回文子串就是一个对称的子串
//我们可以考虑从中间开始向两边扩展
//或者我们从两边向中间收缩
//这里我们使用第一种思路
//注意一个点
//一个字符的子串也是回文子串
//所以当字符串s只有一个字符,返回整个字符串即可
//先计算字符串的长度
int len=strlen(s);
//字符串只有一个字符
if(len<2)
{
return s;
}
//这里借鉴了大佬的思路
//用一个二维数组来表示是否是回文子串
//行表示回文子串的头
//列表示回文子串的尾
//类似于图的存储方法————邻接矩阵法
//因为一个回文子串一定是存在的,并且最短为1
int maxlen=1;
int begin=0;
//创建数组存放是否是回文子串的判断结果
int is_circle[len][len];
//所有单个字符都是回文子串
for(int i=0;i<len;i++)
{
is_circle[i][i]=1;
}
//开始从中间向两边扩展
//我们只要找到一边的字符个数,另一边是对称的
//所以我们从左边开始遍历,右边就会对称着向前遍历
//把中心左边的字符个数设置为2,包括中心
//因为像bb这种情况,中心就是bb,是俩个字符
for(int left=2;left<=len;left++)
{
//设置中心从左边位置开始
for(int i=0;i<len;i++)
{
//找右边界
int right=left+i-1;
//如果右边界越界就退出循环
if(right>=len)
{
break;
}
//从两边向中心开始收缩判断
if(s[i]!=s[right])
{
is_circle[i][right]=0;
}
else
{
//右边到中心的距离为0 1 2
//1.aba
//2.abcba abba
//0.bb
if(right-i<3)
{
is_circle[i][right]=1;
}
else
{
is_circle[i][right]=is_circle[i+1][right-1];
}
}
//是回文子串并且子串长度大于1
if(is_circle[i][right]&&right-i+1>maxlen)
{
maxlen=right-i+1;
begin=i;
}
}
}
//在子串后面设置一个'\0'标志结束
s[begin+maxlen]='\0';
s=&s[begin];
return s;
}