leetcode 5. 最长回文子串 c++ 三种解法

题目如下:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

我一共写了三种解法,分别是暴力搜索,动态规划和manacher算法(马拉车算法),时间分别为3180ms,1196ms和12ms,因此manacher算法在解这题的时候时间复杂度远远小于其他两种算法。这也是leetcode的优点吧,可以横向学习和比较各种算法,加深对各种复杂算法的理解。以下先放代码,具体解释以后再更新。

参考博文网址如下:

暴力搜索:

具体网址忘了,那个博主其实也就是给了思路,没给参考代码,大概意思就是选一个点,向两边伸展,对比元素是否对称,比较麻烦的地方是需要考虑对称串是奇数串还是偶数串的问题。

动态规划:

https://blog.csdn.net/shineboyxxb/article/details/52079360

manacher算法:

https://www.cnblogs.com/mini-coconut/p/9074315.html

https://www.cnblogs.com/love-yh/p/7072161.html

暴力搜索:

string longestPalindrome(string s)  //暴力搜索
{
	int length = 0;
	string maxStr;
	int totalSize = s.length();
	for (int i = 0; i < totalSize; i++)
	{
		int lengthTemp1=0;
		string temp1;
		int lengthTemp2=0;
		string temp2;
		for (int j =0;; j++)
		{
				if ((i - j < 0) || (i + j > totalSize - 1))
				{
					break;
				}
				if (s[i - j] == s[i + j])
				{
					temp1 = s.substr(i - j, 2 * j + 1);
					lengthTemp1 = 2 * j + 1;
				}
				else
				{
					break;
				}
		}

		for (int j = 0;; j++)
		{
			if (i + 1>totalSize-1)
			{
				break;
			}
			if (s[i] == s[i + 1])
			{
				if (i - j<0 || i + 1 + j>totalSize - 1)
				{
					break;
				}
				if (s[i - j] == s[i + j + 1])
				{
					temp2 = s.substr(i - j, 2 * j + 2);
					lengthTemp2 = 2 * j + 2;
				}
				else
				{
					break;
				}
			}
			else
			{
				break;
			}
		}
		if (lengthTemp1<lengthTemp2)
		{
			lengthTemp1 = lengthTemp2;
			temp1 = temp2;
		}
		if (length < lengthTemp1)
		{
			length = lengthTemp1;
			maxStr = temp1;
		}
	}
	return maxStr;
}

动态规划:

string longestPalindrome(string s)  //动态规划
{
    int size = s.size();
	vector<vector<bool>> dp(size,vector<bool>(size,false));
	int start = 0;
	int maxLength = 1;
	for (int i = 0; i < size; i++)
	{
		for (int j = 0; j <=i; j++)
		{
			if (i - j < 2)
			{
				dp[j][i] = (s[j]==s[i]);
			}
			else if (i - j >= 2)
			{
				dp[j][i] = (s[j] == s[i]) && (dp[j+1][i-1]);
			}
			if (dp[j][i] && maxLength < i - j + 1)
			{
				maxLength = i - j + 1;
				start = j;
			}
		}
	}
	return s.substr(start,maxLength);
}

manacher算法:

string longestPalindrome(string s)  //manacher算法
{
	string newStr = "$#";
	for (int i = 0; i < s.length(); i++)
	{
		newStr += s[i];
		newStr += "#";
	}
	vector<int> Len(newStr.length(), 0);
	int pos = 0, mx = 0;
	int start = 0, maxLen = 0;
	for (int i = 1; i < newStr.size(); i++)
	{
		Len[i] = i < mx ? min(Len[2 * pos - i], mx - i) : 1;
		while (i + Len[i] < newStr.size() && i - Len[i]>0 && newStr[i + Len[i]] == newStr[i - Len[i]])
			Len[i]++;
		if (i + Len[i] > mx) //如果新计算的最右侧端点大于mx,则更新pos和mx
		{
			pos = i;
			mx = i + Len[i];
		}
		if (Len[i] - 1 > maxLen)
		{
			start = (i - Len[i]) / 2;
			maxLen = Len[i] - 1;
		}
	}
	return s.substr(start, maxLen);
}

猜你喜欢

转载自blog.csdn.net/qq_38279908/article/details/88344758