*LeetCode:Longest Palindromic Substring


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

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


1、算法描述:

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

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

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

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

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

step2: 将问题划分成3种情况考虑,即左:left_result、右:right_result、跨界:cross_result。然后依次递归调用函数Search_Palindrome寻找回文子串。最后比较left_resultright_resultcross_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结果是正确的,如下所示。



对于其他可以自行验证。针对未接受的原因或者程序中的缺点,希望大家给出宝贵的意见,谢谢!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值