[轉]O(n)迴文子串演算法 Manacher演算法

來源:互聯網
上載者:User

標籤:

  這裡,我介紹一下O(n)迴文串處理的一種方法。Manacher演算法.
原文地址:
http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear-time-algorithm-for-finding-longest-palindrome-sub-string/
    其實原文說得是比較清楚的,只是英文的,我這裡寫一份中文的吧。
    首先:大家都知道什麼叫迴文串吧,這個演算法要解決的就是一個字串中最長的迴文子串有多長。這個演算法可以在O(n)的時間複雜度內既線性時間複雜度的情況下,求出以每個字元為中心的最長迴文有多長,
    這個演算法有一個很巧妙的地方,它把奇數的迴文串和偶數的迴文串統一起來考慮了。這一點一直是在做迴文串問題中時比較煩的地方。這個演算法還有一個很好的地方就是充分利用了字元匹配的特殊性,避免了大量不必要的重複匹配。
    演算法大致過程是這樣。先在每兩個相鄰字元中間插入一個分隔字元,當然這個分隔字元要在原串中沒有出現過。一般可以用‘#’分隔。這樣就非常巧妙的將奇數長度迴文串與偶數長度迴文串統一起來考慮了(見下面的一個例子,迴文串長度全為奇數了),然後用一個輔助數組P記錄以每個字元為中心的最長迴文串的資訊。P[id]記錄的是以字元str[id]為中心的最長迴文串,當以str[id]為第一個字元,這個最長迴文串向右延伸了P[id]個字元。
    原串:    w aa bwsw f d
    新串:   # w # a # a # b # w # s # w # f # d #
輔助數組P:  1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
    這裡有一個很好的性質,P[id]-1就是該迴文子串在原串中的長度(包括‘#’)。如果這裡不是特別清楚,可以自己拿出紙來畫一畫,自己體會體會。當然這裡可能每個人寫法不盡相同,不過我想大致思路應該是一樣的吧。
    好,我們繼續。現在的關鍵問題就在於怎麼在O(n)時間複雜度內求出P數組了。只要把這個P數組求出來,最長迴文子串就可以直接掃一遍得出來了。
    由於這個演算法是線性從前往後掃的。那麼當我們準備求P[i]的時候,i以前的P[j]我們是已經得到了的。我們用mx記在i之前的迴文串中,延伸至最右端的位置。同時用id這個變數記下取得這個最優mx時的id值。(註:為了防止字元比較的時候越界,我在這個加了‘#’的字串之前還加了另一個特殊字元‘$’,故我的新串下標是從1開始的)
好,到這裡,我們可以先貼一份代碼了。

 

    void pk()    {        int i;        int mx = 0;        int id;        for(i=1; i<n; i++)        {            if( mx > i )                p[i] = MIN( p[2*id-i], mx-i );                    else                p[i] = 1;            for(; str[i+p[i]] == str[i-p[i]]; p[i]++)                ;            if( p[i] + i > mx )            {                mx = p[i] + i;                id = i;            }        }    }

 

   代碼是不是很短啊,而且相當好寫。很方便吧,還記得我上面說的這個演算法避免了很多不必要的重複匹配吧。這是什麼意思呢,其實這就是一句代碼。

  if( mx > i )    p[i]= MIN( p[2*id-i], mx-i ); 就是當前面比較的最遠長度mx>i的時候,P[i]有一個最小值。這個演算法的核心思想就在這裡,為什麼P數組滿足這樣一個性質呢?   (下面的部分為圖片形式)

    看完這個演算法,你有可能會覺得這種演算法在哪會用到呢?其實迴文串尾碼數組也可以做。只是複雜度是O(n log n)的,而且一般情況下也不會刻意去卡一個log n的演算法。可正好hdu就有這麼一題,你用尾碼數組寫怎麼都得T(當然應該是我寫得太爛了)。不信的話大家也可以去試試這題。

        http://acm.hdu.edu.cn/showproblem.php?pid=3068
    另外,順便附一份AC代碼。
        http://acm.hust.edu.cn:8080/judge/problem/viewSource.action?id=140283

 

[轉]O(n)迴文子串演算法 Manacher演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.