馬拉車和字典樹

2022-08-20 07:03:12 字數 2251 閱讀 2146

馬拉車演算法:用於求解最長回文子串的問題。因為它能夠以o(n)的時間複雜度求解答案,因此十分的高效。

演算法思想:馬拉車演算法主要是利用已求解的回文子串內部具有對稱性,借由此來進行加速處理。

舉個例子:

1.字串:abbababa        最長回文子串:5(abbababa

2.字串:abcbbabbc      最長回文子串:7(abcbbabbc

3.字串:abccbaba        最長回文子串:6(abccbaba)

傳統方法是,遍歷每個字元,以該字元為中心向兩邊查詢。時間複雜度為o(n^2),效率很差;

在此基礎上可以先對字串雜湊一下,然後用二分求解,可以達到o(nlogn)

最後最優的求解此類問題的演算法就是我們的馬拉車演算法了,他達到了神奇的o(n)

回文串分為奇回文和偶回文,而我們的馬拉車演算法進行了乙個騷操作,將所有回文子串都處理成了奇回文。我們在每個字元的前邊和後邊都插入乙個沒有出現過的字元,最後再在最前面插入乙個沒有出現過的字元(防止越界),就可以達到這個神奇的效果。

舉個例子:

字串:abbababa

變換之後:$#a#b#b#a#b#a#b#a#\0

回文子串:#a#, #a#b#a#b#a#

這樣變換後的字串中的回文子串就都變成了奇回文。

我們規定以s[i]為中心的回文子串的半徑為p[i],即回文子串的長度為2 * p[i] - 1,如上邊#a#b#a#b#a#,回文半徑為6,長度為11,還可以得出原字串此時對應的回文子串長度為5,即p[i] - 1 = 6 - 1 = 5。

可以多畫幾個例子看看,這個是根據變換後字串的規律得到的。

那麼,p[i]應該如何計算呢。

我們計算的時候從左往右計算。由圖我們可知此時p[j](j = 2 * id - i)已經計算出來了。圖中表示現在(2 * id - mx, mx)區域內為乙個回文子串,因此我們可以得知p[i] = p[j] (i < mx),然後再迴圈檢索一下以i為中心還能再擴大半徑不,就可以求得p[i],話不多說,上**:

const int maxn = 2e6 + 7;

char s[maxn], a[maxn]; int p[maxn];

int manacher(char s, int len)

a[l] = 0;

int mx = 0, id = 0, maxlen = -1;

for (int i = 1; i < l - 1; i++)

return maxlen;

}

然我們來看看例題:

acwing: 

演算法思想:利用空間換取時間。預處理建一棵樹,把內容都記錄下來,如下:

(標橙色的節點是「目標節點「,即根節點到這個目標節點的路徑上的所有字母構成了乙個單詞。)

字典樹就是一棵樹,樹邊記錄了一些字元,結點記錄了一些標記資訊。

這就是字典樹的概念。結合上面說的概念,上圖所示的字典樹包括的單詞分別為:

a

abcbac

bbcca

根據字典樹的概念,我們可以發現:字典樹的本質是把很多字串拆成單個字元的形式,以樹的方式儲存起來。所以我們說字典樹維護的是」字典「。那麼根據這個最基本的性質,我們可以由此延伸出字典樹的很多妙用。簡單總結起來大體如下:

字典樹的兩種基本操作為建樹和查詢。

儲存資料結構:

const int maxn = 2e5 + 7;

int trie[maxn][26], col[maxn], tot = 1;

char s[maxn];

其中,trie[i][j]表示乙個指向子節點的指標,col[i]表示乙個終止標記,tot記錄現有的結點個數

插入操作:

void insert(char*s) 

col[p] = 1

;}

查詢操作:

bool search(char*s) 

return col[p] == 1

;}

來看看例題:

馬拉車演算法

思路筆記 上述情況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 題意在給定的字串中找...