Manacher's Algorithm——搜索最長迴文串

Manacher's Algorithm——搜索最長迴文串

最近刷leetcode刷到一個尋找最長迴文串的題,想了很久都沒想出能夠將算法複雜度降低至O(n2)以下的方法,只能上網搜求答案:Manacher’s Algorithm 馬拉車算法

這篇文章將Manacher算法分爲兩個重點:

  1. 對字符串進行修改,在每個字符兩邊添加標識符#,而後在字符串首另外添加符號$ ,於是乎字符串abcdcba變爲$#a#b#c#d#c#b#a#,根據原文中的求解,原迴文串長度l0與現迴文串半徑r1的關係爲l0 = r1 -1,而原迴文串的起始位置p0 = (m1 - r1) / 2,其中m1爲現迴文串的中心點位置
  2. 逐字符掃描,新增兩個變量mx和id,mx爲當前已知所有迴文串的右邊界中最大的那一個(所有處於已知迴文串的字符的位置均小於mx),id則爲該回文串的中心位置,此時有p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1; 其中p[i]爲第i個字符的半徑,即我們正在掃描的字符的半徑

其中1比較好理解,但是2有點費解,這裏按照我自己的思路去解釋2,manacher算法其實是基於中心擴展法的一個優化,對於我們正在掃描字符s[i],有兩種情況:(1)獨立存在 (2)被包含在另一個迴文串中,manacher算法正是基於這兩種情況給出了優化方案:

  1. mx <= i,很明顯,當前正在掃描的字符s[i]不被包含在任何一個已知的迴文串中,所以我們只能根據中心擴展法,一個一個的乖乖掃描出以s[i]爲中心的迴文串半徑
  2. mx > i,i被包含在迴文串h中(h的右邊界即爲mx),這裏又分兩種情況,2*id-i 是i在迴文串h中的對稱位置,如果mx-i > p[2*id-i],根據對稱原則,以i爲中心的迴文串被全包含在迴文串h中,所以p[i]=p[2*id-i],否則的話,p[i]的半徑至少爲mx-i,然後我們就只能繼續往右逐字符掃描,計算出p[i]的真實值

原文作者已經貼出他自己的代碼,這裏就不贅述了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章