LeetCode Longest Palindromic Substring

本文探讨了三种不同的算法来解决寻找字符串中最长回文子串的问题:暴力法、动态规划以及Manacher算法的改进版。通过对每种方法的逐步解析,展示了如何优化算法以达到更好的时间和空间效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次提交,,直接处理,时间为O(n三次方),时间限制,不通过。

bool dist(string s,int i,int j)
{
	while(i<j)
	{
		if (s[i]!=s[j])
		{
			return false;
		}
		i++;j--;
	}
	return true;
}
string longestPalindrome(string s) {
	int strlen=s.length();
	if (strlen<=1)
	{
		return s;
	}
	int maxdis=0,maxi,maxj;
	for (int i=0;i<strlen;i++)
	{
		for (int j=i+1;j<strlen;j++)
		{
			if (dist(s,i,j)&&(j-i+1)>maxdis)
			{
				maxdis = j-i+1;
				maxi = i;
				maxj = j;
			}
		}
	}
	return s.substr(maxi,maxj-maxi+1);
}
第二次提交,改用动态规划,空间限制,不通过。

string longestPalindrome2(string s) {
	int strlen=s.length();
	if (strlen<=1)
	{
		return s;
	}
	bool **max = new bool*[strlen];
	for (int i=0;i<strlen;i++)
	{
		max[i] = new bool[strlen];
	}
	for (int i=0;i<strlen;i++)
	{
		max[i][i] = true;
		if (i<strlen-1)
		{
			if (s[i]==s[i+1])
				max[i][i+1] = true;
			else
				max[i][i+1] = false;
		}
	}
	for (int k=2;k<strlen;k++)
	{
		for (int i=0;i<strlen-k;i++)
		{
			int j = i + k;
			if (max[i+1][j-1]&&s[i]==s[j])
			{
				max[i][j] = true;
			}
			else
				max[i][j] = false;
		}
	}
	/*for (int i=0;i<strlen-2;i++)//this is wrong
	{
		for (int j=i+2;j<strlen;j++)
		{
			if (max[i+1][j-1]&&s[i]==s[j])
			{
				max[i][j] = true;
			}
			else
				max[i][j] = false;
		}
	}
	for (int i=0;i<strlen;i++)
	{
		for (int j=i;j<strlen;j++)
		{
			cout<<max[i][j]<<" ";
		}
		cout<<endl;
	}*/
	int maxdis=0,maxi,maxj;
	for (int i=0;i<strlen-1;i++)
	{
		for (int j=i+1;j<strlen;j++)
		{
			if (max[i][j]&&maxdis<j-i+1)
			{
				maxdis = j-i+1;
				maxi = i;
				maxj = j;
			}
		}
	}
	
	for (int i=0;i<strlen;i++)
	{
		delete[] max[i];
	}
	delete[] max;
	return s.substr(maxi,maxdis);
}
第三次提交过了,这题因为以前看过, http://blog.youkuaiyun.com/littlestream9527/article/details/12224437

string longestPalindrome3(string s) {
	int strlen=s.length();
	if (strlen<=1)
	{
		return s;
	}
	string str="@#";
	for (int i=0;i<strlen;i++)
	{
		str+=s[i];
		str+="#";
	}
	int p[2005], mx = 0, id = 0;//其中id表示最大回文子串中心的位置,mx则为id+P[id],也就是最大回文子串的边界。
	memset(p, 0, sizeof(p));
	for (int i = 1; str[i] != '\0'; i++) {
		p[i] = mx > i ? min(p[2*id-i], mx-i) : 1;
		while (str[i + p[i]] == str[i - p[i]]) p[i]++;
		if (i + p[i] > mx) {
			mx = i + p[i];
			id = i;
		}
	}
	//S  #  1  #  2  #  2  #  1  #  2  #  3  #  2  #  1  #
	//P  1  2  1  2  5  2  1  4  1  2  1  6  1  2  1  2  1
	int maxdis=0,maxi;
	for (int i=0;i<2005;i++)
	{
		if (p[i]>maxdis)
		{
			maxdis = p[i];
			maxi = i;
		}
	}
	//cout<<" maxi is  "<<maxi<<"  maxdis is  "<<maxdis<<endl;
	string tempstr1,tempstr2="";
	tempstr1 = str.substr(maxi-maxdis+1,2*maxdis-1);
	//cout<<"tempstr1 is "<<tempstr1<<endl;
	for (int i=0;i<tempstr1.length();i++)
	{
		if (tempstr1[i]!='#')
		{
			tempstr2+=tempstr1[i];
		}
	}
	return tempstr2;

}
什么时候还得回头看看,忘得太快了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值