Manacher 求最长回文子串算法
??? Manacher算法,是由一個叫Manacher的人在1975年發明的,可以在$O(n)$的時間復雜度里求出一個字符串中的最長回文子串。
??? 例如這兩個回文串“level”、“noon”,Manacher算法先對其進行一個處理:
??? level ?? -->? #l#e#v#e#l#
??? noon ? ?--> ? ?#n#o#o#n#
??? 這樣的好處就是,不論回文子串的長度是奇是偶,最后求出的回文子串長度都是奇數的,就不用分類討論了。
??? 我們用p[i]表示以i為中心的最長回文子串向兩邊擴展的長度,例如:
??? s ??? #? 1? #? 2? #? 2? #? 1 ? #? 2? #? 3? #? 2? #? 1? #
??? p ??? 1? 2? 1? 2? 5? 2? 1? 4?? 1? 2? 1??6? 1? 2? 1? 2? 1
??? 我們發現,p[i]-1剛好為原串以i位置為中心的最長回文子串長度。
??? 在Manacher算法中,需要兩個輔助變量。id為當前最長回文子串的中心,mx為以id為中心的最長回文子串的右邊界(id+p[id])。這個算法的核心部分在這里:
?
if(mx>i)p[i]=min(p[(id<<1)-i],mx-i);else p[i]=1;???? 當 mx - i > p[j] 的時候,以s[j]為中心的回文子串包含在以s[id]為中心的回文子串中,由于 i 和 j 對稱,以S[i]為中心的回文子串必然包含在以S[id]為中心的回文子串中,所以必有 p[i] = p[j]。
???? 當 p[j] > mx - i 的時候,以s[j]為中心的回文子串不完全包含于以s[id]為中心的回文子串中,但是由于對稱性,以s[i]為中心的回文子串,其向右至少會擴張到mx的位置,也就是說 p[i] >= mx - i。至于mx之后的部分是否對稱,就只能一個一個匹配了。
???? 當 mx? < i 的時候,我們就無法對 p[i] 進行更多的推算,只能一個一個匹配。
?
?
???? 上圖給出了Manacher的詳解和線性復雜度的證明。
???? 以下是核心代碼:
C++ Code:
void manacher(){int mx=0,id=0;for(i=1;i<=n;++i){if(mx>i)p[i]=min(p[(id<<1)-i],mx-i);else p[i]=1;while(s[i-p[i]]==s[i+p[i]])++p[i];if(i+p[i]>mx)mx=i+p[id=i];} }?
轉載于:https://www.cnblogs.com/Mrsrz/p/7308621.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Manacher 求最长回文子串算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javaScript——廖雪峰老师学习笔
- 下一篇: BZOJ 1009: [HNOI2008