馬拉車演算法用於解決回文串問題,個人經常會忘記其原理,所以在此整理一下。
對於回文串,簡單說即正著念和反著念是一樣的字串,如abba。用常規的暴力方法,即以乙個字元為中心,兩邊分別外擴,比較每個字元。這種方法需要分奇偶來討論,即如aba和abba這兩種情況。
1.馬拉車演算法首先需要對字串進行處理,在字串開頭結尾及字元間穿插同乙個特殊字元,該字元可以是任何字元,不影響結果。
2.這裡引入兩個變數,分別是r和c。下面將解釋兩個變數的意義。
假設下圖方框表示以a為中心的回文字串
我們用乙個陣列array來表示對以應位置的字元為中心,其最長的回文字串長度。即array[7] = 8。那麼我們知道,在以a為中心的回文字串中,因為對稱的關係,左右兩邊有著相同的子串
依照這個特性,後面字元的array值,是可以參考前面對稱位置字元的array值的。r的作用是框定當前回文半徑最長的距離(只增不減),即上圖14的位置,而c則是以r為半徑的回文串中心。這裡分兩種情況。
(1)若當前i的位置小於r(即如上圖在紅框內),則以其對稱位置2c-i的array值為基礎,再向外擴充套件。
(2)若i大於r,即在紅框外,array初始值設為1,則需要按照之前的方式,兩邊展開來比較,無優化。比較完後再更新r和c值。
//預先處理字串
string getmancher
(string str)
res[
2*str.
length()
]='#';
return res;
}int
maxbackstr
(string str)
if(r
) max =
max(max,array[i]);
}return max-1;
}int
main()
對字串要進行遍歷,由於r不會回退,故時間複雜度為o(n)。 馬拉車演算法
思路筆記 上述情況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 的暴力演算法,馬拉車演算法無疑是求解最長回文子串的最優選擇。最長回文子串分為偶數串和奇數串,為了避免這些問題,馬...
馬拉車演算法
manacher char s maxn 1 int n,hw maxn 1 int l maxn 1 r maxn 1 void manacher char a n len 2 2 s n 0 int maxr 0,m 0 for int i 1 i n i manacher 題意在給定的字串中找...