Counting palindromic substrings in O(n)

后端 未结 3 1516
情书的邮戳
情书的邮戳 2020-12-07 15:01

Given a string (assume only English characters) S of length n, we can count the number of palindromic substrings with the following algorithm:

相关标签:
3条回答
  • 2020-12-07 15:29

    The following site shows an algorithm for computing the longest palindromic substring in O(n) time, and does so by computing the longest palindromic substring at every possible center and then taking the maximum. So, you should be able to easily modify it for your purposes.

    http://www.akalin.cx/2007/11/28/finding-the-longest-palindromic-substring-in-linear-time/

    EDIT: The first link looks a little shaky upon closer inspection, so here's another one:

    http://zhuhcheng.spaces.live.com/Blog/cns!DE38E96268C49F28!311.entry?wa=wsignin1.0&sa=707413829

    0 讨论(0)
  • 2020-12-07 15:42

    For "normal" strings it should be rather efficient to look at each character as the potential "center" of a palindrome and then check if the surrounding characters actually build one:

    # check odd palindromes
    for center in range(len(ls)):
       # check how many characters to the left and right of |center|
       # build a palindrome
       maxoffs = min(center, len(ls)-center-1)
       offs = 0
       while offs <= maxoffs and ls[center-offs] == ls[center+offs]:
          offs += 1
       offs -= 1
       print ls[center-offs : center+offs+1]                                    
    
    # check for even palindromes
    for center in range(len(ls)-1):
       maxoffs = min(center, len(ls)-center-2)
       offs = 0
       while offs <= maxoffs and ls[center-offs] == ls[center+offs+1]:
          offs += 1
       offs -= 1
       if offs >= 0:
          print ls[center-offs : center+offs+2]
    

    For normal strings this should be about O(n), though in the worst case, for example if the string consists of only one character repeated over and over again, it will still take O(n2) time.

    0 讨论(0)
  • 2020-12-07 15:45

    Consider a string S="aaabb".

    Append a character '$' at both ends of the string and in between every two consecutive characters to change the string to S="$a$a$a$b$b$" and apply Manacher's algorithm for this string S.

    New string S is of length 2n+1 which gives us runtime of O(2n+1) which is same as O(n).

    index :  1 2 3 4 5 6 7 8 9 10 11
    A     :  1 3 5 7 5 3 1 3 5  3  1
    S     :  $ a $ a $ a $ b $  b  $
    

    Array A is the result of Manacher's Algorithm.

    Now, the summation of A[i]/4 for index where '$', else (A[i]+1)/4 for every other character from 1<=i<=n is your answer.

    Here, $ acts as a center for the even length palidromic substrings and the odd length can be calculated normally. The answer for this case is:

    0 + 1 + 1 + 2 + 1 + 1 + 0 + 1 + 1 + 1 + 0 = 9 (a,a,aaa,a,b,b,aa,aa,bb).

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题