manacher算法是用来求解最长回文串的问题。最长回文串的解法一般有暴力法、动态规划、中心扩展法和manacher算法。
暴力法的时间复杂度为\(O(n^3)\),一般都会超时;
动态规划的时间复杂度和空间复杂度均为\(O(n^2)\),通过矩阵压缩存储,空间复杂度常数可以降低为0.5,但时间复杂度较高,基本不能再优化;
中心扩展法在性能上优于动态规划,空间复杂度为\(O(1)\),但时间复杂度仍然是\(O(n^2)\);
manacher性能最好,时间复杂度和空间复杂度均为\(O(n)\)
//中心扩展法的代码
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() == 0)return "";
int maxlen = 1, start = 0;
for(int i = 0; i < s.size(); ++i){
int len1 = expand(s, i, i);
int len2 = expand(s, i, i + 1);
int len = max(len1, len2);
if(len > maxlen){
start = i - (len - 1) / 2;
maxlen = len;
}
}
return s.substr(start, maxlen);
}
private : int expand(const string &s, int l, int r){
while(l >= 0 && r < s.size() && s[l] == s[r]){
l--;
r++;
}
return r - l - 1;
}
};
中心扩展法造成时间复杂度高的原因主要有两个方面:
第一点从代码可以看出,第二点见插图:
对第 \(j\)个字符进行中心扩展时, 子串\(s[0, j - 1]\)都已经进行了中心扩展,以每个字符为中心的回文串信息都已经获得,在这些回文串中必然存在一个最长的回文串\(s[mx, my]\),其对称中心记作\(id\)。如果\(j < my\),则\(j\)一定有一个对称位置\(i\),假设以\(i\)为中心的回文串为左侧绿色的子串,则以\(j\)为中心的绿色子串一定也是回文串。但是中心扩展法忽略了这点,对这部分子串进行了重复比对。
manacher算法主要是对中心扩展法的两方面不足进行改进。
为了不区分奇数和偶数两种情况,manacher对字符串进行了预处理,在长度为\(n\)的字符串的空隙中填入\(n+1\)相同的字符,使字符串的总长度变为\(2n + 1\)。
例如:
对于字符串
abbac
,处理之后为#a#b#b#a#c#
(假设插入的字符为#
)
处理之后的字符串与原字符串的映射关系为:\(s[i] = temps[2 * i + 1]\)
\(i\)号位置之前有 \(i+1\)个gap
处理后的最大回文串长度与原来的长度的关系:\((tempLmax - 1) / 2 = lmax\)
数据结构
回文半径数组\(radius[len]\)
\(radius[i] = (tempLmax(i) - 1) / 2\),含义为字符\(temps[i]\)右侧的字符个数(不懂网上很多版本为什么带上\(temps[i]\))
最大覆盖范围\((id, mx)\),\(id\)为对称中心
算法实现
string longestPalindrome(string s) {
if(s.size() == 0)return "";
string temps = "#";
for(int i = 0; i < s.size(); ++i){
temps += s[i];
temps += '#';
}
int len = temps.size();
int radius[len] = {0};
int id = 0, mx = 0;
int start = 0, maxlen = 0;
for(int i = 1; i < len; ++i){
if(i < mx){
radius[i] = min(radius[2 * id - i], mx - i);
}
for(int dl = radius[i] + 1; i - dl >= 0 && i + dl < len; ++dl){
if(temps[i - dl] == temps[i + dl])radius[i]++;
else break;
}
if(radius[i] + i > mx){
id = i;
mx = radius[i] + i;
}
if(radius[i] > maxlen){
start = (i - radius[i]) / 2;
maxlen = radius[i];
}
}
return s.substr(start, maxlen);
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章