介紹:manacher是一種用來求字串子串中最長回文長度,時間複雜度可以達到o(n
)o(n)
o(n)
級別。下面先介紹暴力求解法。
思路:
①求出字串的所有子串,時間複雜度為o(n
2)o(n^2)
o(n2
)。設定指標lef
t,ri
ghtleft,right
left,r
ight
,分別表示子串的左右下標,在第乙個for迴圈列舉出所有可能的lef
tleft
left
,在第二個for迴圈列舉出在lef
tleft
left
情況下,所有可能的rig
htright
right。
②判斷字串為回文字串的方法,時間複雜度為o(n
)o(n)
o(n)
。把字串翻轉,與原來字元比較如果相同即為回文字串。
源**
bool
ispalindromes
(string s,
int,
int)
;void
findsubstring
(string s)}}
}
前方高能!!下面進入正文
原理:對於奇數長度的字串,如s="
abcb
a"s="abcba"
s="abc
ba",肯定有乙個中心位置,如c
cc,左右分別是對稱的區域,如果從第0個開始遍歷,就會有乙個時時更新的最右回文字元。比如,從第乙個a開始最右的回文字元是是s[0
](a)
s[0] (a)
s[0](a
),到c時最右字元是s[4
](a)
s[4](a)
s[4](a
)。可能有人會問了這樣做有什麼用,接下來我就介紹如何利用這個最右邊界。
假設這個最右邊界為max
nmaxn
maxn
,這個最右邊界的中心為cen
tercenter
center
,當前位置的下標為ser
vial
servial
servia
l。①如果ser
vial
servial
servia
l位於這個最右邊界內,即ser
vial
xnservialse
rvialxn
,根據對稱我們可以找到左邊的字母,如前面字串中s[4
]as[4]a
s[4]
a對應s[0
]as[0]a
s[0]a。
根據前面的字母我們可以知道該字母的回文長度,如果長度的一半−1-1
−1沒有超過左邊界,那麼很明顯右邊字母的回文長度等於左邊的那個,這裡畫**釋一下吧。
如果超過了左邊界,那麼就是說左邊字母有些字元是不包含在這個最右的回文字元中的,所以我們只能先確定一部分回文字元(最右的座標減去ser
vial
∗2+1
servial*2+1
servia
l∗2+
1),而右邊的無法確定。
②如果ser
vial
servial
servia
l本來就不在最右字串裡面,就可以先讓它的回文長度為1
11,然後開始向搜尋。這個應該好理解,就不畫圖了,有不懂的dd我。
這兩種進行更新時,如果超過了回文字串的最右邊界,記得更新邊境。
如果你以為這樣就玩了,那你就錯了,如果是字串是偶數個時,我們是找不到,所謂的cen
tercenter
center
,所以我們在每乙個字元中間插入乙個字串沒有的字元如∗
*∗,最後還在開頭跟結尾插入另兩個字元作為哨兵。因此具體的做法也要稍稍調整一下,我們只用紀錄長度的一半就好,因為有一半是無關的字元∗*∗。
如我們把aba
abaab
a,變為∗a∗
b∗a∗
*a*b*a*
∗a∗b∗a
∗,長度由3
33變到了7
77,其實我們只要記錄b
bb和後面的長度即可,為4
44,4−1
4-14−
1即為正確結果。
對於偶數個的如aaaa
aa,變為∗a∗
a∗*a*a*
∗a∗a
∗,記錄一半的長度為3
33,3−1
3-13−
1,ok
!ok!
ok!
最後分別給一下兩部分的函式
int
transform
(char
*ori)
cur[
2*len+1]
='*'
; cur[
2*len+2]
='$'
;//哨兵
cur[
2*len+3]
='0'
;//字串結束的標誌
return
2*len+1;
}int
manacher
(char
*cur,
int len)
ans=
max(ans,len[t]);
}return ans-1;
//由於補充字元的結果,在紙上畫一下很容易看出來的ok!
ok!ok
!搞定,我寫部落格的目的主要是為了鞏固知識,所以有部分會借鑑一下。
部分引用於這。
Manacher 馬拉車演算法
給定乙個字串,求出其的最長回文子串 乙個將時間複雜度優化到o n 的演算法 暴力演算法,但不是純暴力,即按照做過的事情不再去做來優化 我們知道,乙個回文串要麼是奇數的串 aba 要麼是偶數的串 abba 可以看出,乙個回文串有乙個對稱軸 對於奇數串aba來說,對稱軸就是b 而對於偶數串abba來說,...
Manacher演算法(馬拉車)
演算法總結第三彈 manacher演算法,前面講了兩個字串相演算法 kmp和拓展kmp,這次來還是來總結乙個字串演算法,manacher演算法,我習慣叫他 馬拉車 演算法。相對於前面介紹的兩個演算法,manacher演算法的應用範圍要狹窄得多,但是它的思想和拓展kmp演算法有很多共通支出,所以在這裡...
馬拉車演算法manacher
1.預處理解決奇回文和偶回文問題 比如 str bcbaa 在每個字元的開頭,結尾和中間插入乙個特殊字元 來得到乙個新的字串 b c b a a 這樣對於原來字串中的奇回文 bcb 來說,在新的字串中變成了 b c b 還是奇回文,只是回文串長度從3變成了7 注意 中 i 1 0,與1按位與,如果i...