馬拉車演算法總結

2022-03-01 13:08:45 字數 1537 閱讀 1976

【演算法簡述】

馬拉車(manacher)演算法是在o(n)時間內解決尋找源字串的最長回文子串s的問題的演算法。

樸素演算法情況下對於每乙個s[i]都要左右遍歷其最大回文子串,所以時間複雜度是o(n2)

【演算法原理】

充分利用之前求得的s【j】,為求s【i】服務。

預處理:在每個字元左右兩邊插入#將字串變成奇數串

演算法核心:

p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;

其中p[i]為s[i]的回文半徑,mx為i之前某一回文串右側最遠延伸到的位置,id為該回文串的中心點位置,很顯然從mx的對稱點到mx這一段是關於id對稱的。

如何利用之前求得的s[j]來求s[i]的回文串長度呢?

分情況討論

(1) 當 i在mx左側,p[j] < mx - i,即s[j]的回文子串的左端點不會超過mx的對稱點,那麼很顯然s[i]的回文子串的右端點不會超過mx,所以此時取p[i] = p[j]

(2)當i在mx左側, p[j] > mx - i時,即s[j]的回文子串的左端點超過mx的對稱點,那麼很顯然s[i]的回文子串的右端點至少要到mx,至於mx右側的,只能乙個乙個匹配以確定p[i]了。

(3)當i在mx右側,即i > mx,初始化p[i] = 1.這時候很顯然,mx和id是要更新的。因為此時回文串右側延伸的位置已經超過mx了。

【模板】

//

返回源字串s的最長回文子串

string manacher(string

s)

//新建p陣列,大小和t串一致,初始化為0 ,p[i]表示以t[i]為中心的回文串半徑

vector p(t.size() , 0

);

//設定重要引數 mx(某回文串延伸到的最右邊下標),id(mx所屬回文串中心下標),

//recenter(結果最大回文串中心下標),relen(最大長回文長度)

int mx = 0, id = 0, recenter = 0, relen = 0

;

//遍歷t字串

for(int i=1; i)

//更新結果資料

if(p[i] >relen)

}relen = (relen*2 - 1) / 2

;

int st = recenter/2 - relen / 2

;

return

s.substr(st , relen) ;

}

Mancher演算法總結 馬拉車

本文在這篇文章的基礎上完成。下面說下mancher演算法。一 mancher可以解決的問題 1 字串轉換 回文字串長度可是奇數,也可是偶數。為了方便處理,我們通過在每個字元之間以及字元首位加特殊符號的方式來統一奇偶問題。舉個例子 s abba 變為t a b b a 我們會發現s的長度是4,而t的長...

馬拉車演算法

思路筆記 上述情況1和情況2又可以歸結為 i 的回文半徑 和 r i的距離 中小的那個就是i的回文半徑。include include includeusing namespace std string manacherstring string str return res int min int...

馬拉車演算法

馬拉車演算法是一種計算最長回文子串的演算法,以其優秀的線性複雜度聞名於世,相較於o n 2 o n 2 o n2 的dpdp dp演算法和會被特殊資料卡到o n 2 o n 2 o n2 的暴力演算法,馬拉車演算法無疑是求解最長回文子串的最優選擇。最長回文子串分為偶數串和奇數串,為了避免這些問題,馬...