假设现有字符串arr[]="12HHHHA",需要从字符串中找到最长的回文子串。
首先我们 从第一个数开始,判断这个字符的两侧的字符是否相同,如果相同回文数组的长度就会扩大2,如果不相同就判断下一个数。
但是遇到几个重复的字符且数量为偶数个,那么这种向两边判断的方法就失效了,因此在遇到这种情况时,需要额外的处理一下。
因为这些字符相同,所以这些字符肯定能组成一个回文字符串,因此我们可以++right来跳过这些重复的字符,再进行判断left和right所指的字符是否相同。之后遍历整个数组,找到最长的回文子串。
int main()
{
char arr[2500]={0};
scanf("%s",arr);
int len=strlen(arr);
int max=0;
for(int i=0;i<len;i++)//中心扩散法
{
int left=i-1,right=i+1;
int sz=1;
while(right<len&&arr[right]==arr[i])//跳过重复的字符
{
right++;
sz++;
}
while(left>=0&&right<len&&arr[right]==arr[left])//判断是否相同
{
sz+=2;
left--;
right++;
}
if(sz>max)
max=sz;
}
printf("%d",max);
return 0;
}
5. 最长回文子串 - 力扣(LeetCode)
记录子串的左右边界,比较找到最大的子串后,将该子串的后一位改为\0,返回该子串的首字母地址,即是最长的子字符串。
char * longestPalindrome(char * s){
if(strlen(s)==0||strlen(s)==1)
return s;
int i,start,left,right,count,len;
start = len =0;
for(i=0;s[i]!='\0';i+=count){//以每个字符为中心向两侧寻找
count = 1;
left=i-1;
right = i+1;
while(s[right]!='\0'&&s[i]==s[right]){ //处理重复字符串
right++;
count++;//重复字符的个数
}
while(left>=0 && s[right]!='\0' && s[left] == s[right]){//向两侧寻找重复的字符
left--;
right++;
}
if(right-left-1>len){//扩大子串的边界
start = left+1;//记录首字母地址和长度
len = right-left-1;
}
}
s[start + len] = '\0'; // 原地修改
return s + start;
}
时间复杂度O(n^2)
空间复杂度O(1)