Manacher's Algorithm 馬拉車算法

題目:Longest Palindromic Substring

題目簡(jiǎn)述

找出最長(zhǎng)回文子串卿叽,如輸入"babad",結(jié)果為"bab"或"aba"啤呼。

馬拉車算法

引入

可以觀察到回文串根據(jù)中心對(duì)稱吧兔,反之可以從中心向兩邊擴(kuò)張去尋找最大回文串。一共有2n+1個(gè)中心浊竟,每個(gè)都嘗試一下便可以得出答案。為了操作方便津畸,添加分隔符#振定。
如:babaabac——> #b#a#b#a#a#b#a#c


image.png

T為加分割符后的字符串,L[i]代表以T[i]為中心的最長(zhǎng)回文子串的長(zhǎng)度肉拓。最后找出最大的L為13后频,(13-1)/2后為原字符串的最長(zhǎng)回文子串的長(zhǎng)度。

上述算法時(shí)間復(fù)雜度為O(n2),在具體求解每個(gè)L[i]時(shí)都需要O(n)的時(shí)間復(fù)雜度暖途,有沒有辦法可以提高效率呢卑惜?

若從左向右遍歷求解,回文串的特性可以發(fā)揮一定作用驻售。設(shè)L[0]-L[8]已求出露久,且已經(jīng)得知T[8]為中心,左邊界為T[2],右邊界為T[14]是回文串。那么接下來(lái)L[9]=L[7]=3,L[10]=L[6]=1,.....欺栗,但注意L[3]!=L[13]毫痕。具體分析看下文。

根據(jù)回文特性簡(jiǎn)化

若前面已經(jīng)求出了以C為中心迟几,R為右邊界的某個(gè)回文串消请,現(xiàn)在正要求的以i為中心的最大回文串長(zhǎng)度。若i<=R类腮,則可以根據(jù)對(duì)稱規(guī)則求解臊泰,若i>R則只能蠻力求解。

設(shè)P為回文半徑蚜枢,即表示以字符T[i]為中心的最長(zhǎng)回文字串的最端右字符到T[i]的長(zhǎng)度因宇。注:P[i]-1 即為原回文子串的長(zhǎng)度

四種情況

  1. i>R
    T[i-1]與T[i+1]匹配...T[i-2]與T[i+2]匹配...直至超出字符串邊界七婴,或T[i-k]!=T[i+k]

  2. i<=R且i+(P[i']-1)<R
    P[i] = P[i']

  3. i<=R且i+(P[i']-1)>R
    P[i] = R-i+1
    例:如下圖,由于T[15]!=T[11]回文串被截?cái)?/p>

    截?cái)?jpg

    有沒有可能T[15]==T[11]呢察滑?
    若T[15]=T[11](已知T[11]=T[5]=T[1]),則T[1]=T[15]修肠,P[8]=7+1與P[8]=7矛盾贺辰,所以T[15]不可能等于T[11]。因此一定會(huì)被截?cái)唷?/p>

  4. i<=R且i+(P[i']-1)=R
    P[i]>=R-i+1
    首先嵌施,P[i]至少可以是R-i+1饲化,后面可能會(huì)有其他的字符使得回文子串繼續(xù)加長(zhǎng),但也可能沒有吗伤。具體有沒有需要再一一匹配吃靠,但匹配的基礎(chǔ)是R-i+1。T[i-(R-i+1)]與T[(i+(R-i+1)]匹配..T[i-(R-i+2)]與T[(i+(R-i+2)]匹配...

Python代碼

class Solution:
    def longestPalindrome(self, s: str) -> str:
        c = 0
        r = -1
        T = '#' + '#'.join(s) + '#'
        P = [1]*(len(T))
        max_index = 0
        for i in range(len(T)):
            if i<= r:
                P[i] = min(r-i+1,P[2*c-i])
            # Try to extend
            while i-P[i]>=0 and i+P[i]<len(T) and T[i+P[i]]==T[i-P[i]]:
                P[i] += 1
            # 循環(huán)中順便找出最長(zhǎng)回文子串的中心
            if P[i]>P[max_index]: 
                max_index = i
            if i+P[i]-1 >r:
                c = i
                r = i+P[i]-1
        #根據(jù)映射關(guān)系返回原子串
        return(s[(max_index-P[max_index]+2)//2:(max_index+P[max_index]-2)//2+1])
if __name__ == "__main__":
    l = 'babad'
    t = Solution()
    r = t.longestPalindrome(l)
    print(r)

總結(jié)

  1. 通過(guò)加分割符的方法足淆,使每個(gè)中心位置都可以取到巢块,也使字符串長(zhǎng)度統(tǒng)一為奇數(shù)
  2. 馬拉車算法主要運(yùn)用的是回文串的特性

Reference:

  1. https://www.hackerrank.com/topics/manachers-algorithm

  2. http://javabin.cn/2018/manacher.html

  3. https://www.cnblogs.com/love-yh/p/7072161.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市巧号,隨后出現(xiàn)的幾起案子族奢,更是在濱河造成了極大的恐慌,老刑警劉巖丹鸿,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件越走,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡靠欢,警方通過(guò)查閱死者的電腦和手機(jī)廊敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)门怪,“玉大人骡澈,你說(shuō)我怎么就攤上這事⌒嚼拢” “怎么了秧廉?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)拣帽。 經(jīng)常有香客問(wèn)我疼电,道長(zhǎng),這世上最難降的妖魔是什么减拭? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任蔽豺,我火速辦了婚禮,結(jié)果婚禮上拧粪,老公的妹妹穿的比我還像新娘修陡。我一直安慰自己沧侥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布魄鸦。 她就那樣靜靜地躺著宴杀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拾因。 梳的紋絲不亂的頭發(fā)上旺罢,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音绢记,去河邊找鬼扁达。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蠢熄,可吹牛的內(nèi)容都是我干的跪解。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼签孔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叉讥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起骏啰,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤节吮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后判耕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體透绩,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年壁熄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了帚豪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡草丧,死狀恐怖狸臣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昌执,我是刑警寧澤烛亦,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站懂拾,受9級(jí)特大地震影響煤禽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岖赋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一檬果、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦选脊、人聲如沸杭抠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)偏灿。三九已至,卻和暖如春角寸,著一層夾襖步出監(jiān)牢的瞬間菩混,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工扁藕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疚脐。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓奠蹬,卻偏偏與公主長(zhǎng)得像废膘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容