一)第一步是改造字串 s,變為 t,其改造的方法如下:對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定在字串 s 的字元之間和 s 的首尾都插入乙個 '#',如:s=「abba」變為 t="#a#b#b#a#" 。我們會發現 s 的長度是 4,而 t的長度為 9,長度變為奇數了!!那 s 的長度為奇數的情況時,變化後的長度還是奇數嗎?我們舉個例子,s=「abcba」 變化為 t=「#a#b#c#b#a#」,t 的長度為 11,所以我們發現其改造的目的是將字串的長度變為奇數,這樣就可以統一的處理奇偶的情況了。
二)第二步,為了改進回文相互重疊的情況,我們將改造完後的 t[i] 處的回文半徑儲存到陣列 p[i] 中,p[i] 為新字串 t 的t[i] 處的回文半徑,表示以字元t[i]為中心的最長回文字串的最端右字元到 t[i] 的長度,如以 t[i] 為中心的最長回文子串的為t[l,r],那麼 p[i]=r-i+1。這樣最後遍歷陣列 p[i],取其中最大值即可。若 p[i]=1 表示該回文串就是 t[i] 本身。舉乙個簡單的例子感受一下:
陣列p有一性質,p[i]-1 就是該回文子串在原字串 s 中的長度,那就是 p[i]-1 就是該回文子串在原字串 s 中的長度,至於證明,首先在轉換得到的字串 t 中,所有的回文字串的長度都為奇數,那麼對於以 t[i] 為中心的最長回文字串,其長度就為 2*p[i]-1,經過觀察可知,t 中所有的回文子串,其中分隔符的數量一定比其他字元的數量多 1,也就是有 p[i] 個分隔符,剩下 p[i]-1 個字元來自原字串,所以該回文串在原字串中的長度就為 p[i]-1。
另外,由於第乙個和最後乙個字元都是 '#' ,且也需要搜尋回文,為了防止越界,我們還需要在首尾再加上非#號字元,實際操作時我們只需給開頭加上個非 '#' 號字元,結尾不用加的原因是字串的結尾標識為 '\0',等於預設加過了。這樣原問題就轉化成如何求陣列 p[i] 的問題了。
三)如何求陣列 p[i]
從左往右計算陣列 p[ ],mi 為之前取得最大回文串的中心位置,而r是最大回文串能到達的最右端的值。
1)當 i<=r 時,如何計算 p[i] 的值了?毫無疑問的是陣列p中點 i 之前點對應的值都已經計算出來了。利用回文串的特性,我們找到點 i 關於 mi 的對稱點 j,其值為 j=2*mi-i 。因點 j 、i 在以 mi 為中心的最大回文串的範圍內[l ,r]。
a)那麼如果p[j] b)如果p[j]>=r-i(即 j 為中心的回文串的最左端超過 l),即以點 j 為中心的最大回文串的範圍已經超出了範圍 [l,r] ,這種情況,等式 p[j]=p[i] 還成立嗎?顯然不總是成立的!因以點 j 為中心的回文串的最左端超過l,那麼在[l, j]之間的字元肯定能在 [j, mi] 找到相等的,由回文串的特性可知,p[i] 至少等於 r- i,至於是否大於 r-i,我們還要從 r+1 開始一一的匹配,直達失配為止,從而更新 r 和對應的 mi 以及 p[i]。
2)當 i > r時,沒法利用到回文串的特性,只能老老實實的一步步去匹配。
is pat&tap symmetric?
,最長對稱子串為s pat&tap s
,於是你應該輸出11。
輸入在一行中給出長度不超過1000的非空字串。
在一行中輸出最長對稱子串的長度。
is pat&tap symmetric?
11
#includeusing namespace std;
const int maxn = 10000005;
int v[maxn];
char str[maxn];
int main()
maxlen = max(v[i]-1,maxlen);
} cout << maxlen << endl;
return 0;
}
最長對稱子串(馬拉車演算法)
對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定 is pat tap symmetric?最長對稱子串為 s pat tap s 於是你應該輸出11。輸入格式 輸入在一行中給出長度不超過1000的非空字串。輸出格式 在一行中輸出最長對稱子串的長度。輸入樣例 is pat tap symm...
最長對稱子串 馬拉車演算法
7 1 最長對稱子串 25 分 對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定is pat tap symmetric?最長對稱子串為s pat tap s,於是你應該輸出11。輸入在一行中給出長度不超過1000的非空字串。在一行中輸出最長對稱子串的長度。is pat tap symme...
最長回文子串(馬拉車演算法)
最長回文子串,即正反讀起來都一樣,例如 ababa manacher algorithm演算法利用了回文的重複特性,讓時間複雜度降為了o n 馬拉車演算法詳解 改造字串,在中心擴充套件法中,要求區分字串長度為奇數或偶數的情況,我們這裡對字串進行簡單的改造,讓字串變成奇數便於處理。例 ababad a...