如果想了解更多內容,歡迎關注我的微信公衆號:信息學競賽從入門到巔峯。
今天,我們來證明一下Manacher的時間複雜度。
先貼上Manacher算法的模板:
s[0] = '$'; s[++m] = '#';
for (b = 1; ss[b] != '\0'; ++b) {
s[++m] = ss[b];
s[++m] = '#';
}
s[++m] = '?';
for (int i = 1; i < m; ++i) {
if (maxid > i) p[i] = min(maxid-i, p[2*id-i]);
else p[i] = 1;
while (s[i-p[i]] == s[i+p[i]]) p[i]++;
if (i + p[i] > maxid) {
maxid = i + p[i];
id = i;
}
}
我們考慮產生複雜度的地方,分別是最外層對整個字符串的遍歷和每次對迴文串擴展的while。
顯然,最外層的for循環是O(N)的,那麼我們只需要證明while的總循環次數也是O(N)級別的即可。
很容易發現,每次進入while,迴文串的最大覆蓋範圍都會加1.(爲什麼呢?)
1、如果以i位置的爲迴文中心的迴文串的基礎長度沒有超出當前迴文串的最大覆蓋範圍,那麼顯然不會進入while中(由於對稱性,該回文串的長度已經最大了)。
2、如果以i位置的爲迴文中心的迴文串的基礎長度超出了當前回文串的最大覆蓋範圍,那麼顯然每進入一次while,迴文串的最大覆蓋範圍都會加1.
那麼,當最大覆蓋範圍包含了整個字符串之後,while循環就不會在進入了。所以while循環的總次數爲O(N)。
綜上所述,Manacher算法的時間複雜度爲O(N)。