您的位置:首页 > 其它

*LeetCode:Longest Palindromic Substring

2015-07-21 13:24 369 查看


问题描述:给定一个字符串,寻找最长回文子串。

猜想:当拿到这个问题,最初的想法打算用分治法来解,也许是受到近期在看算法导论的影响,其实它跟算法导论里"最大子数组"问题类似。但是,唯一的不足:没有被accepted,但是在vs2010里我解决了这个问题。针对这个问题,我花费2天的时间去完善,但是仍然存在瑕疵,故想记录下来当时的想法,也希望得到你们的帮助。

1、算法描述:

step1: 先考虑特殊情况,或者说是最小子问题。

若字符串只有一个字符即len=1;

若字符串len=2,则只需考虑两者是否相等;

若字符串len=3进行处理;

(任何的问题的解,都可以分解成以上子问题解的组合)

step2: 将问题划分成3种情况考虑,即左:left_result、右:right_result、跨界:cross_result。然后依次递归调用函数Search_Palindrome寻找回文子串。最后比较left_result、right_result、cross_result三者的回文子串长度,选择最长的结果返回。

2、具体实现参考以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct result_palindrome
{

char *_low;
char *_high;
int _sum;

}Result;

char *s_buf;

//declaration
Result *Cross_search_palindrome(char *s_start, char *s_mid, char *s_end, int len);
bool Compare_literal(char *s_start, char *s_end, char *str, int len);

Result *Search_Palindrome(char *s_start, char *s_end, int len);
char* longestPalindrome(char* s);

bool Compare_literal(char *s_start, char *s_end, char *str, int len)
{

int i,j;
for (i=1,j=len; i<=j; i++,j--)
{
if (*s_start!=*str || *s_end!=*str)
{
return false;
}
s_start++;
s_end--;
}
return true;
}

Result *Cross_search_palindrome(char *s_start, char *s_mid, char *s_end, int len)
{
Result *result=NULL;
int length=0;
bool Com_result;
char *max_left;
char *max_right;

char *_left, *_right;
_left=s_mid-1;
_right=s_mid+1;

result=(Result*)malloc(sizeof(Result)*1);
if (result==NULL)
{
printf("error in memory in function Cross_search_palindrome\n");
}

for (; _left!=s_start && _right!=s_end; _left--,_right++)
{
if (*_left!=*_right)
{
/*length=_right-_left+1-2;*/
result->_sum=2*length+1;//come error
result->_low=_left+1;
result->_high=_right-1;

return result;
}
length++;
}

if (_left!=s_start /*&& _right==s_end*/)
{

if (*_left!=*_right)
{
length=length;
result->_sum=2*length+1;//come error
result->_low=_left+1;
result->_high=_right-1;

return result;//forget return
}
length++;
_left--;

Com_result=Compare_literal(_left+1,_right,_left,2*length+1);
if (Com_result==false)
{
result->_sum=2*length+1;//come error
result->_low=_left+1;
result->_high=_right;

return result;
}

//all element is the same
/*length=length+1;*/
result->_sum=2*length+2;//come error
result->_low=_left;
result->_high=_right;

return result;

}
else
{

if (*_left!=*_right)
{
result->_sum=2*length+1;
result->_low=_left+1;
result->_high=_right-1;

return result;
}
length++;
result->_sum=2*length+1;
result->_low=_left;
result->_high=_right;

return result;
}

}

Result *Search_Palindrome(char *s_start, char *s_end, int len)
{
if (len==2)
{
Result *result2=(Result*)malloc(sizeof(Result)*1);
if (*s_start==*s_end)
{

result2->_low=s_start;
result2->_high=s_end;
result2->_sum=2;

return result2;
}
else
{
result2->_low=NULL;
result2->_high=NULL;
result2->_sum=0;

return result2;
}
}

if (len==3)
{
Result *result3=(Result*)malloc(sizeof(Result)*1);
if (*s_start==*s_end)
{
result3->_sum=3;
result3->_low=s_start;
result3->_high=s_end;

return result3;
}
else if (*s_start==*(s_start+1))
{
result3->_sum=2;
result3->_low=s_start;
result3->_high=(s_start+1);

return result3;
}
else if (*(s_start+1)==*s_end)
{
result3->_sum=2;
result3->_low=(s_start+1);
result3->_high=s_end;

return result3;
}

}

if (s_start==s_end)
{
Result *result4=(Result*)malloc(sizeof(Result)*1);
result4->_low=s_start;
result4->_high=s_end;
result4->_sum=1;

return result4;
}
else
{

Result *left_result=(Result*)malloc(sizeof(Result)*1);
Result *right_result=(Result*)malloc(sizeof(Result)*1);
Result *cross_result=(Result*)malloc(sizeof(Result)*1);

left_result=Search_Palindrome(s_start,s_start+len/2,len/2+1);
right_result=Search_Palindrome(s_start+len/2+1,s_end,len/2-1);

cross_result=Cross_search_palindrome(s_start,s_start+len/2,s_end,len);
if (left_result->_sum>=right_result->_sum && left_result->_sum>=cross_result->_sum)
{
return left_result;
}
else if (right_result->_sum>=left_result->_sum && right_result->_sum>=cross_result->_sum)
{
return right_result;
}
else if (cross_result->_sum>=left_result->_sum && cross_result->_sum>=right_result->_sum)
{
return cross_result;
}
}
}

char* longestPalindrome(char* s) {
//count the length of s
int length=0;
int Palindrome_length=0;
char *low, *high;
char *c_s=s;
char *result_palindrome=NULL;
char *buf;

while(*c_s!='\0')
{

length++;
c_s++;
}
printf("string length is %d\n",length);

low=s;
high=s+length-1;
Result *back_value=Search_Palindrome(low,high,length);
if (back_value==NULL)
{
printf("something wrong in function Search_Palindrome\n");
exit(-1);
}
Palindrome_length=back_value->_sum;
printf("Palindrome string length is %d\n",Palindrome_length);

//open a new memory
result_palindrome=(char*)malloc(sizeof(char)*length);
if (result_palindrome==NULL)
{
printf("error in open memory\n");
exit(-1);
}
buf=result_palindrome;

low=back_value->_low;
high=back_value->_high;

while(low!=high)
{

*result_palindrome=*low;
low++;
result_palindrome++;
}
*result_palindrome=*low;
*(result_palindrome+1)='\0';
result_palindrome=buf;

return result_palindrome;

}
主函数:

void main()
{

char str[]="cfcaeff";//"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";//"zeusnilemacaronimaisanitratetartinasiaminoracamelinsuez"
char *back_str=longestPalindrome(str);

if (back_str==NULL)
{
printf("something wrong in function longestPalindrome\n");
exit(-1);
}

printf("longestPalindrome is %s\n",back_str);
/*	free(back_str);*/
return;
}


3、结果

当给定字符串"cfcaeff",最长回文子串为"cfc",实验结果如下。



最后给出unaccepted的原因:






但是,当给定长度为1000的字符串"cccc....cccc"时,vs2010结果是正确的,如下所示。






对于其他可以自行验证。针对未接受的原因或者程序中的缺点,希望大家给出宝贵的意见,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: