题目: 给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
1、自己当时写的,暴力
char * longestPalindrome(char * s){
//暴力
char str[1005]={};
int maxlen=0,start=0,end=0,len=strlen(s);
if(len == 0)//空
{
return s;
}
for(int i=0; i<=len; i++)//1-len
{
for(int j=len; j>=i+maxlen; j--)//检测从i到j这串字符是否满足回文,并且大于等于现有的最大的长度
{//等于是因为这里从后往前查询,需要输出第一个满足条件的
strncpy(str,s+i,j-i+1);//将字符串拷贝到str中并判断
if(Isp(str,j-i+2))
{
start = i;
end = j;
maxlen=j-i+1;
}
}
}
s[end+1]='\0';
return s+start;
}
int Isp(char *str, int len)//判断回文
{
int flag = 1,left=0,right=len-2;
while(left<=right)
{
if(str[left] != str[right])
{
flag = 0;
break;
}
left++;
right--;
}
return flag;
}
2、动态规划,现学的
char * longestPalindrome(char * s){
//动态规划
int table[1001][1001]={0};
int len=strlen(s);//字符长度
int start=0,end=0;//起始和结束
int maxlen=0;//记录最长回文长度
if(len > 1)
{
maxlen=1;
}
else
{
return s;
}
//length=1
for(int i=0,length=1; i<len; i++)
{
table[i][i] = 1;
}
//length=2
for(int i=0,length=2; i<len-1; i++)
{
int j=i+1;
if(s[i] == s[j])
{
table[i][j]=1;
}
if(table[i][j] && length>maxlen)//长度相同时只记录第一组
{
start = i;
end = j;
maxlen = length;
}
}
//length>2
for(int length=3; length<=len; length++)
{
for(int i=0; i<=len-length; i++)
{
int j=i+length-1;
if(s[i] != s[j])
{
table[i][j]=0;
continue;
}
else
{
table[i][j] = table[i+1][j-1];//状态为上一次记录的状态,比如本次长度5,0和4相同,则查看1和3的状态(之前记录过的)
}
if(table[i][j] && length>maxlen)//长度相同时只记录第一组
{
start = i;
end = j;
maxlen = length;
}
}
}
s[end+1]='\0';
return s+start;
}
3、中心扩展
char * longestPalindrome(char * s){
//中心扩展
int len=strlen(s);//字符长度
int start=0,end=0;//起始和结束
int maxlen=0;//记录最长回文长度
int left=0,right=0;//扩展的位置
if(len > 1)
{
maxlen=1;
}
else
{
return s;
}
//奇数
for(int i=1+maxlen/2; i<len-1-maxlen/2; i++)//从比当前maxlen/2大的位置开始到比当前maxlen/2大的位置结束
{
left=i-1;
right=i+1;
while(left>=0 && right<len)
{
if(s[left] != s[right])
{
break;
}
else
{
if((right-left+1) > maxlen)
{
start = left;
end = right;
maxlen = right-left+1;
}
}
right = right+1;
left = left-1;
}
}
//偶数
for(int i=1+maxlen/2; i<len-maxlen/2; i++)//从比当前maxlen/2大的位置开始到比当前maxlen/2大的位置结束
{
left=i-1;
right=i;
while(left>=0 && right<len)
{
if(s[left] != s[right])
{
break;
}
else
{
if((right-left+1) > maxlen)
{
start = left;
end = right;
maxlen = right-left+1;
}
}
right = right+1;
left = left-1;
}
}
s[end+1]='\0';
return s+start;
}
Python3:中心扩展
class Solution:
def longestPalindrome(self, s: str) -> str:
sSize=len(s);
maxlen=0
start=end=0
left=right=0
if(sSize < 1):
return s
else:
maxlen=1
# 奇数
for i in range(1+(int)(maxlen/2),sSize-(int)(maxlen/2)):
left=i-1
right=i+1
while(left>=0 and right<sSize):
if(s[left] != s[right]):
break
else:
if(right-left+1 > maxlen):
start = left
end = right
maxlen = right-left+1
left = left-1
right = right+1
#偶数
for i in range(1+(int)(maxlen/2),sSize-(int)(maxlen/2)):
left=i-1
right=i
while(left>=0 and right<sSize):
if(s[left] != s[right]):
break
else:
if(right-left+1 > maxlen):
start = left
end = right
maxlen = right-left+1
left = left-1
right = right+1
return s[start:end+1]