Leetcode Promblem5

Longest Palindromic Substring 最长回文串

这个一开始我只能用暴力法来求解,结果时间复杂度应该是达到了O(n^3),运行速度严重落后。

在网上看到了用动态规划来做的,方法如下:使用一个二维数组dp[][],若dp[i][j]=1表示第i个位置到第j个位置的字符串是回文。当i=j时,dp[i][j]=1;当i=j+1时,说明他们是相邻位置,所以只要比较s[i]和s[j]是否相等;当i>j+1时,除了判断s[i]和s[j]相等之外,dp[i + 1][j - 1]若为真,就是回文串。由于题目中要找到最长的回文串,则需要设置一个变量保存最长的长度和字符串的位置。每当找到一个回文串时,需要判定是否是最长的回文串,如果是,记录其位置。时间复杂度为O(n^2)。接下来介绍一种时间复杂度为O(n)的算法。

Manacher's Algorithm 马拉车算法
先在字符串里添加符号使得个数为奇数(例如:ababa变为#a#b#a#b#a#),然后计算以每个字符为中心的每个回文子串的半径。(其中p[i]表示以t[i]字符为中心的回文子串的半径,若p[i] = 1,则该回文子串就是t[i]本身。如上面例子的p为121415142)。计算p的方法:
p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;
id表示最大回文子串中心的位置,mx表示回文串能延伸到的最右端的位置。2id-1为位置i以id为中心的对称点。在mx>i的情况下,如果p[2*id-1]>mx-i,代表j=2id-1这个点的回文串不包括在id的回文串内,所以只能已知p[i]=mx-i,后面的需要比较。如果p[2*id-1]<mx-i,那么代表j=2*id-1这个点的回文串在id的回文串内,此时p[i]=p[j]。其余情况只能老老实实去比较 。
while (t[i + p[i]] == t[i - p[i]]) ++p[i];
然后比较出最长回文串。

猜你喜欢

转载自www.cnblogs.com/nihwo/p/9402538.html