9

I know you can find the longest palindromic substring in O(n) with manacher's algorithm, but is it possible to find the total number of palindromic substrings in O(n) or O(n log n)? If so, how would you go about doing it?

Count single letters as palindromes too.


So for example, the number of palindromic substrings of "xyxyx" is 9.

This is because you have:

5 single letter palindromes (x,y,x,y,x)
3 palindromes with three letters (xyx, yxy, xyx)
1 palindrome with five letters (xyxyx)

for a total of 5+3+1 = 9 palindromic substrings.
1110101001
  • 4,662
  • 7
  • 26
  • 48
  • 5
    I'd be interested to see if this is possible, since the maximum number of palindromic substrings is O(n^2). – templatetypedef Jan 04 '14 at 00:27
  • 1
    It seems to me that it's impossible to achieve a worst-case better than `O(n²)`, since the mere act of incrementing a counter for each of the substrings would be `O(n²)` given a highly-palindromic input. – StriplingWarrior Jan 04 '14 at 00:31
  • When I tried the best I could get O(n^2), and for an input like "aaaaaa..." it would take too long. – 1110101001 Jan 04 '14 at 00:35
  • 2
    @StriplingWarrior- That said, you can count inversions in an array in O(n log n) time even though there can be Theta(n^2) inversions by adding values other than 1 to the counter. – templatetypedef Jan 04 '14 at 00:38
  • 2
    I've given (what I think is) a linear time algorithm below, but seeing as I came up with it on the spot I'd appreciate it if you guys and gals could check it over. It's passed the examples I've tried and feels correct, but the more eyes the better. – Andy Jones Jan 04 '14 at 01:46

1 Answers1

7

A substring S' of a string S is a maximal palindrome of radius i iff starting at the middle it reads the same in both directions for i characters, but not for i+1 characters.

Any palindrome in a string must be a substring of a maximal palindrome with the same center. Conversely, every substring of a maximal palindrome with the same center must also be a palindrome. We can also easily count the number of sub-palindromes with the same center: a palindrome of length k contains Ceiling(k/2) of them.

Seeing as we can find all maximal palindromes using Manacher's algorithm in linear time, we have a linear time algorithm for your problem: find the array of lengths of the maximal palindromes, divide by two, take the ceiling, sum the array.

Example 1: on "xyxyx", the maximal palindromes are

x, xyx, xyxyx, xyx, x

and Manacher's can be used to calculate an array

1, 0, 3, 0, 5, 0, 3, 0, 1

representing the lengths of the maximal palindromes centered at each letter and in each gap between letters. Anyway, applying the map Ceiling(k/2) to the entries, we get

1, 0, 2, 0, 3, 0, 2, 0, 1

which sums to 9.

Example 2: "abba". Maximal palindromes are

a, b, abba, b, a

Manacher's can be used to get the array

1, 0, 1, 4, 1, 0, 1

and the Ceiling(k/2)'d array is

1, 0, 1, 2, 1, 0, 1

for a sum of 6 (a, b, b, a, bb, abba).

Andy Jones
  • 4,723
  • 2
  • 19
  • 24
  • Wow.. seems like it might work. How did you get that a palindrome of length k has ceil(k/2) sub-palindromes? – 1110101001 Jan 04 '14 at 01:53
  • 1
    It only has `ceil(k/2)` subpalindromes with the same center; we are not concerned about other subpalindromes. – Sergey Orshanskiy Jan 04 '14 at 01:56
  • @user2612743 Think of it this way: each palindrome in a string has the same center as exactly one maximal palindrome. So we can partition the set of all palindromes according to which maximal palindrome they share a center with. The number of elements in a partition is then `Ceil(k/2)`, where `k` is the length of the longest palindrome in that partition. – Andy Jones Jan 04 '14 at 02:08
  • Got it. The logic seems sound and the algorithm seems to work fine -- I think I'll accept it! – 1110101001 Jan 04 '14 at 02:26
  • how are you calculating `maximal palindromes` ? – Aseem Goyal Mar 24 '14 at 18:53
  • As in the array of lengths of the maximal palindromes? [This algorithm](http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html) – Andy Jones Mar 24 '14 at 19:34