Given a string, find the minimum number of deletions required to convert it into a palindrome.

For example, consider string ACBCDBAA. The minimum number of deletions required is 3.

A C B C D B A A  or  A C B C D B A A ——> A B C B A

Practice this problem

The idea is to use recursion to solve this problem. The idea is to compare the last character of the string X[i…j] with its first character. There are two possibilities:

  1. If the string’s last character is the same as the first character, no deletion is needed, and we recur for the remaining substring X[i+1, j-1].
  2. If the last character of the string is different from the first character, return one plus the minimum of the two values we get by:
    • Deleting the last character and recursing for the remaining substring X[i, j-1].
    • Deleting the first character and recursing for the remaining substring X[i+1, j].

This yields the following recursive relation:

T[i…j] = | T[i+1…j-1]                        (if X[i] = X[j])
         | 1 + min (T[i+1…j], T[i…j-1])      (if X[i] != X[j])

The algorithm can be implemented as follows in C++, Java, and Python. It finds the minimum number of deletions required to convert a sequence X into a palindrome recursively using the above relations.

C++


Download  Run Code

Output:

The minimum number of deletions required is 3

Java


Download  Run Code

Output:

The minimum number of deletions required is 3

Python


Download  Run Code

Output:

The minimum number of deletions required is 3

The worst-case time complexity of the above solution is exponential (O(2n)), where n is the length of the input string. The worst case happens when there is no repeated character present in X, and each recursive call will end up in two recursive calls. It also requires additional space for the call stack.

 
The problem has an optimal substructure. We have seen that the problem can be broken down into smaller subproblems, which can further be broken down into yet smaller subproblems, and so on. The problem also exhibits overlapping subproblems, so we will end up solving the same subproblem over and over again. Let’s consider the recursion tree for a sequence of length 6 having all distinct characters, say ABCDEF.

LPS problem

 
As we can see, the same subproblems (highlighted in the same color) are getting computed repeatedly. We know that problems with optimal substructure and overlapping subproblems can be solved by dynamic programming, where subproblem solutions are memoized rather than computed and again. Following is the C++, Java, and Python program that demonstrates it:

C++


Download  Run Code

Output:

The minimum number of deletions required is 3

Java


Download  Run Code

Output:

The minimum number of deletions required is 3

Python


Download  Run Code

Output:

The minimum number of deletions required is 3

The time complexity of the above solution is O(n2) and requires O(n2) extra space, where n is the length of the input string.

 
This problem is also a classic variation of the Longest Common Subsequence (LCS) problem. The idea is to find the Longest Palindromic subsequence of the given string. The minimum number of deletions required will be the difference in length of the string and palindromic subsequence. We can easily find the longest palindromic subsequence by taking the longest common subsequence of the given string with its reverse, i.e., call LCS(X, reverse(X)).

The implementation can be seen below in C++, Java, and Python:

C++


Download  Run Code

Output:

The minimum number of deletions required is 3

Java


Download  Run Code

Output:

The minimum number of deletions required is 3

Python


Download  Run Code

Output:

The minimum number of deletions required is 3

The time complexity of the above solution is O(n2), and the auxiliary space used by the program is O(n2).

 
Exercise: Write bottom-up solution for above recursive top-down version.