回文字符串利器——Manacher算法

最近刷leetcode時(shí),遇到求最長回文子串問題彪见,一開始想的是暴力匹配算法(逐個(gè)字符向兩邊檢索)儡司,發(fā)現(xiàn)花費(fèi)時(shí)間過長,后來了解到Manacher算法企巢,跟大家分享一下枫慷。

一、字符串處理

在暴力匹配算法中浪规,我們以某個(gè)字符為對稱中心或听,分別向兩邊檢索,但問題出現(xiàn)了笋婿。

如果回文子串長度為奇數(shù)誉裆,如: ababa
    當(dāng)我們逐個(gè)匹配時(shí),肯定會找到最長子串缸濒,
但如果長度為偶數(shù)時(shí)足丢, 如: abaaba
    這時(shí)對稱中心不是某個(gè)字符,匹配失敗庇配。

所以斩跌,為了解決這種問題,我們需要對字符串進(jìn)行處理

處理前:  ababa
處理后:   #a#b#a#b#a#
其中'#'為特殊處理字符捞慌,你也可以選擇其它不在字符串中的字符
二耀鸦、計(jì)算長度

我們用一個(gè)數(shù)組 len 來表示處理后回文字符串的長度,len[i] 表示以第i個(gè)字符為對稱中心的回文字符串的半徑+1(自身)啸澡,len[i] -1 表示原字符串(處理前)中以第i個(gè)字符為對稱中心的回文子串長度袖订。如:

    字符串:  #  a  #  b  #  a  #  b  #  a  #
    len[]:  1  2  1  4  1  6  1  4  1  2  1  
    len-1:  0  1  0  3  0  5  0  3  0  1  0
      i :   0  1  2  3  4  5  6  7  8  9  10

我們可以循環(huán)遍歷求得len數(shù)組,但這樣和暴力匹配算法沒啥區(qū)別嗅虏,所以我們來看看Manacher的精髓:
假設(shè)我們求 len[i] 的值洛姑,我們設(shè) len[j] ( j < i ) 中的最大值為R,對應(yīng)的下標(biāo)為J,其意義是以第J個(gè)字符為對稱中心的回文子串 (記為S) 的 半徑+1 = R。Tl,Tr分別為S的左右端點(diǎn)皮服。如圖:

image.png

這時(shí)楞艾,我們需要對 i 所處的位置情況進(jìn)行討論:
當(dāng) i >= Tr参咙,即:

image.png

我們需要依次往兩邊匹配,直到達(dá)到邊界产徊,或者字符不相等昂勒。

當(dāng) i < Tr,關(guān)于 點(diǎn)J 作 i 對稱點(diǎn) ii舟铜,以下標(biāo)ii 為對稱中心的回文字符串記為s

image.png
當(dāng) s 的右端點(diǎn) <= J,即 ii + len[ii] -1 <= J:
此時(shí) len[i] = len[ii]
image.png
當(dāng) s 的 右端點(diǎn) > J 我們會得到一個(gè)必定回文區(qū)域戈盈,
然后在該區(qū)域的端點(diǎn)往兩邊匹配,直到到達(dá)邊界谆刨,或者字符不相等塘娶。
image.png

經(jīng)過一番比較匹配后,我們會得到 len[ i ] ,如果 len [ i ] > R ( ps: len [ J ] ),
則另 R = len [ i ] , J = i ,再計(jì)算 len [ i +1 ] ,直到達(dá)到邊界痊夭。

代碼實(shí)現(xiàn)
......
        int R = 0,J = 0;
        for (int i = 0; i <s.length() ; i++) {
           if(i < R){
               len[i] = Math.min(len[2 * J - i],R-i);  // 尋找最短公共半徑 
           }else{
               len[i] = 1;   // len[i] = 半徑 + 自身刁岸, 所以初始化為1
           }
           while(i - len[i] >= 0 && i + len[i] <s.length()
                   && s.charAt(i- len[i]) == s.charAt(i + len[i])){
               len[i]  += 1;
           }
           if(len[i] > R){
               R = len[i];
               J = i;
           }
        }
......

參考文章:
最長回文子串——Manacher 算法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市她我,隨后出現(xiàn)的幾起案子虹曙,更是在濱河造成了極大的恐慌,老刑警劉巖番舆,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酝碳,死亡現(xiàn)場離奇詭異,居然都是意外死亡恨狈,警方通過查閱死者的電腦和手機(jī)疏哗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來禾怠,“玉大人返奉,你說我怎么就攤上這事÷鹗希” “怎么了芽偏?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長弦讽。 經(jīng)常有香客問我污尉,道長,這世上最難降的妖魔是什么坦袍? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮等太,結(jié)果婚禮上捂齐,老公的妹妹穿的比我還像新娘。我一直安慰自己缩抡,他們只是感情好奠宜,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布包颁。 她就那樣靜靜地躺著,像睡著了一般压真。 火紅的嫁衣襯著肌膚如雪娩嚼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天滴肿,我揣著相機(jī)與錄音岳悟,去河邊找鬼。 笑死泼差,一個(gè)胖子當(dāng)著我的面吹牛贵少,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播堆缘,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼滔灶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吼肥?” 一聲冷哼從身側(cè)響起录平,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缀皱,沒想到半個(gè)月后斗这,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡唆鸡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年涝影,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片争占。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡燃逻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出臂痕,到底是詐尸還是另有隱情伯襟,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布握童,位于F島的核電站姆怪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏澡绩。R本人自食惡果不足惜稽揭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肥卡。 院中可真熱鬧溪掀,春花似錦、人聲如沸步鉴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至喊递,卻和暖如春随闪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背骚勘。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工铐伴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人调鲸。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓盛杰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親藐石。 傳聞我的和親對象是個(gè)殘疾皇子即供,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

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

  • 最長回文子串——Manacher 算法 1. 問題定義 最長回文字符串問題:給定一個(gè)字符串,求它的最長回文子串長度...
    林大鵬閱讀 2,751評論 0 6
  • 上一篇KMP算法之后好幾天都沒有更新于微,今天介紹最長回文子串逗嫡。 首先介紹一下什么叫回文串,就是正著讀和倒著讀的字符順...
    zero_sr閱讀 2,278評論 2 8
  • 引言 字符串匹配一直是計(jì)算機(jī)科學(xué)領(lǐng)域研究和應(yīng)用的熱門領(lǐng)域株依,算法的改進(jìn)研究一直是一個(gè)十分困難的課題驱证。作為字符串匹配中...
    潮汐行者閱讀 1,629評論 2 6
  • 基礎(chǔ)了解 回文串:是一個(gè)正讀和反讀都一樣的字符串。例如:level 恋腕,asdffdsa 回文子串:字符串中抹锄,滿足回...
    來自火星的程序猿閱讀 674評論 0 0
  • 面試算法代碼知識梳理系列 面試算法知識梳理(1) - 排序算法面試算法知識梳理(2) - 字符串算法第一部分面試算...
    澤毛閱讀 1,540評論 0 6