11

Is there a linear-time algorithm to check that a sequence of characters is a concatenation of palindromes? The only thing that comes to my mind is the naive solution:

1. k = 1
2. Split string into k substrings (all possibilities) and check
3. k++
4. repeat

Note: the answer is trivially yes if length 1-strings are defined to be palindromes. Let's assume that this is not the case.

mrk
  • 3,748
  • 23
  • 35

3 Answers3

8

Assuming you want disjoint palindromes, this is known as the PALSTAR problem, and there is a linear time algorithm by Zvi Galil and Joel Seiferas. A Linear-Time On-Line Recognition Algorithm for ``Palstar'.

You can find an explanation of the algorithm in the book here: Text Algorithms (look at linked page and the preceding pages).

If you are ok with a quadratic time algorithm, straight-forward dynamic programming seems to work.

Given a string $s[1,\dots n]$, we maintain an array telling us whether $s[1,\dots j]$ can be decomposed into palindromes.

We also maintain an 2D table which tells us whether $s[i, \dots j]$ is a palindrome or not. This we can construct in $O(n^2)$ time by choosing a center and moving two pointers outwards, checking for palindromes with that center. Do this for each possible center: $\Theta(n)$ centers, each taking $O(n)$ time.

Now, you can check $s[1, \dots j+1]$ whether can be decomposed into palindromes, by checking for each $1 \le i \le j-1$ whether $s[1,\dots i]$ can be decomposed, and if $s[i+1,\dots, j+1]$ is a palindrome (using the above 2D table). This yields a $\Theta(n^2)$ time and $\Theta(n^2)$ space algorithm.

The space usage can be brought down to $O(n)$, if you use Manacher's on-line algorithm to compute whether $s[i+1,\dots j+1]$ is a palindrome (as $i$ goes from $j-1$ to $1$), basically getting rid of the 2D table.

D.W.
  • 167,959
  • 22
  • 232
  • 500
Aryabhata
  • 6,291
  • 2
  • 36
  • 47
4

If overlapping is allowed, it can be done in linear time (in the size of the input string).

Some definitions

Let's define the concept of maximal palindrome:

A maximal palindrome of radius k of a string S is a substring S' such that

  • starting from the centre, S' reads the same k characters in both directions
  • but not for k+1 characters
  • k > 1 (so a single character is not a palindrome)

for example, if S = banana, then S' = anana is a maximal palindrome of radius 2.

A maximal palindrome is a maximal palindrome of radius k for some k.

For example, if S = banana, "ana", "anana", are all its maximal palindromes.

Using maximal palindromes

Now, if we could locate all maximal palindromes of a string, it would be simple to check if the whole string is a concatenation of palindromes.

Take S = abbaccazayaz. Its maximal palindromes are:

  • abba, centered between position 2 and 3, radius = 2
  • acca, centered between position 5 and 6, radius = 2
  • zayaz, centered in position 10, radius = 2

so "abba" spans over [1..4], "acca" spans over [4..7], "zayaz" spans over [8..12]. Since the concatenation of this three palindromes (overlapping is permitted?) spans over the whole string, it follows that "abbaccazayaz" is concatenation of palindromes.

Computing maximal palindromes in linear time

Now, it turns out that we can locate all maximal palindromes of a string S in linear time! *

The idea is to use a suffix tree for S equipped with constant-time lowest common ancestor queries.

So we can check if a string S of length m is a concatenation of palindromes in O(n) time.

* Gusfield, Dan (1997), "9.2 Finding all maximal palindromes in linear time", Algorithms on Strings, Trees, and Sequences

Haile
  • 203
  • 1
  • 6
2

Suppose Palindrome[][] is an array and Palindrome(i,j) is a function which checks, whether substring from i to j is palindrome and returns 1 if is palindrome or returns infinity if is not palindrome, and you looking for smallest number of partitions, create it bottom up:

$$Palindrome[i][i] = 1.$$ $$\forall 0\le i < j < n : Palindrome[i][j] = \min\{Palindrome(i,j), \min_{i\le k<j} \{Palindrome[i,k] + Palindrome[i+1,k]\}\}$$

You should fill $O(n^2)$ cells and each cell takes at most $O(n)$ so algorithm is $O(n^3)$, with a little modification (preprocessing) you can improve it to $O(n^2)$, Also finding this partition is not hard.