【Leet Code】Longest Palindromic Substring ——传说中的Manacher算法

Longest Palindromic Substring

Total Accepted: 17474 Total
Submissions: 84472My Submissions

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest
palindromic substring.

先解释一下题目的意思:

题目要求字符串的回文子字符串,所谓的回文字符串就是从左向右读和从右向左读都一样的字符串,例如:“abcba”或者“abba”

题目还假设字符串的最大长度为1000,而且有且只有一个最大的回文子字符串。

从上面的例子可知,回文字符串有奇偶之分,我们在字符串中插入特殊字符,把偶的情况也作为奇的情况处理:

例:abc -> @#a#b#c#$ (头尾插入不同的特殊字符是为了防止越界)

最简单的方法:

遍历字符串,使用一个数组prad[ ],prad[ i ]保存以第 i 个字符为中心的回文字符串的半径(这个新字符串的半径就刚好等于原字符串的长度)

然后再遍历这个数组就可以轻易得到子回文字符串了:

class Solution
{
public:
	string change(string s)
	{
		string result = "!";
		for (int i = 0; i < s.length(); i++)
		{
			result += "#";
			result += s[i];
		}
		result += "#?";
		return result;
	}
	string longestPalindrome(string s)
	{
		if (0 == s.length())
		{
			return "";
		}
		string new_s = this->change(s);
		int size = new_s.length();
		int* prad = new int[size];
		for (int i = 1; i < size - 1; i++)
		{
			prad[i] = 0;
			while (new_s[i - prad[i] - 1] == new_s[i + prad[i] + 1])
			{
				prad[i]++;
			}
		}
		int maxLen{}, start_pos{};
		for (int i = 1; i < size - 1; i++)
		{
			if (maxLen < prad[i])
			{
				maxLen = prad[i];
				start_pos = (i - maxLen - 1) / 2;
			}
		}
		delete[]prad;
		return s.substr(start_pos, maxLen);
	}
};

该算法的复杂度是O(n2),每一次都重新匹配太浪费时间了,我们可以利用前面匹配得到的信息,将下次匹配的范围缩小一点,这就是传说中的Manacher算法:

class Solution
{
public:
	string change(string s)
	{
		string result = "!";
		for (int i = 0; i < s.length(); i++)
		{
			result += "#";
			result += s[i];
		}
		result += "#?";
		return result;
	}
	string longestPalindrome(string s)
	{
		if (0 == s.length())
		{
			return "";
		}
		string new_s = this->change(s);
		int size = new_s.length();
		int* prad = new int[size];
		int right_end{}, pos{};//记录匹配到的回文字符串达到的最右边,和该字符串的中心位置
		for (int i = 1; i < size - 1; i++)
		{
			if (right_end > i)
			{
				prad[i] = min(right_end - i, prad[2 * pos - i]);
			}
			else
			{
				prad[i] = 0;
			}
			while (new_s[i - prad[i] - 1] == new_s[i + prad[i] + 1])
			{
				prad[i]++;
			}
			if (i + prad[i] > right_end)
			{
				right_end = i + prad[i];
				pos = i;
			}
		}
		int maxLen{}, start_pos{};
		for (int i = 1; i < size - 1; i++)
		{
			if (maxLen < prad[i])
			{
				maxLen = prad[i];
				start_pos = (i - maxLen - 1) / 2;
			}
		}
		delete[]prad;
		return s.substr(start_pos, maxLen);
	}
};
时间: 2024-10-08 04:47:50

【Leet Code】Longest Palindromic Substring ——传说中的Manacher算法的相关文章

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之余全部耗在这上面了,只怪自己基础差.本文主要介绍使用Manacher线性算法来求解字符串的最长回文子字符串. 题目 Given a string S, find the longest palindromic substring in S. You may assume that the maxim

5. Longest Palindromic Substring(最长回文子串 manacher 算法)

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example: Input: "cbbd" Ou

Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Example 2: Input: "cbbd"

LeetCode5 Longest Palindromic Substring

描述:Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 给一个String串,求其中最大的回文字串.这是一个典型的最长回文子串问题,目前有四种解法. 1.暴力测试,测试每个子串,显然这样是最笨的方法,

LeetCode-Algorithms #005 Longest Palindromic Substring, Database #179 Consecutive Numbers

LeetCode-Algorithms #005 Longest Palindromic Substring 英语学习时间palindromic: [医] 复发的, 再发的 在数学和计算机上,就指回文 这道题目就是找出给定字符串中最长的回文子串, 可以假定原字符串的长度不超过1000 直接遍历来做肯定是不难, 但也可以想见一定是慢得可以. 那么我的另一个想法是, 从原串中的每一个字符, 或每两个字符中间的空隙开始, 向左右两边判断是否为回文串, 最后找出最长的 1 class Solution

[string]Longest Palindromic Substring

Total Accepted: 82026 Total Submissions: 379898 Difficulty: Medium Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. Subscrib

[Leetcode] Longest palindromic substring 最长回文子串

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 做这道题之前要先了解什么是回文子串.回文串通俗的解释是,分别从字符串两端开始遍历,得到的结果相同,如"abba",从两端的遍历结果都是:&q

【leedcode】 Longest Palindromic Substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. https://leetcode.com/problems/longest-palindromic-substring/ 求最大回文的长度,其实这道题

LeetCode #5 Longest Palindromic Substring (M)

[Problem] Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. [Analysis] 这题的思路有很多种,网上也有各种讨论.这里我采用的是个人觉得比较好理解的一种利用Dynamic Progra