Minimum number of deletions to make a string palindrome

Given a string of size ‘n’. The task is to remove or delete the minimum number of characters from the string so that the resultant string is a palindrome. 

Note: The order of characters should be maintained. 

Examples : 

Input : aebcbda
Output : 2
Remove characters 'e' and 'd'
Resultant string will be 'abcba'
which is a palindromic string

Input : geeksforgeeks
Output : 8

A simple solution is to remove all subsequences one by one and check if the remaining string is palindrome or not. The time complexity of this solution is exponential.

An efficient approach uses the concept of finding the length of the longest palindromic subsequence of a given sequence. 



Algorithm: 

1. str is the given string.

2. n length of str

3. len be the length of the longest 
  palindromic subsequence of str

4. minimum number of deletions 
  min = n – len

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation to find
// minimum number of deletions
// to make a string palindromic
#include <bits/stdc++.h>
using namespace std;
 
// Returns the length of
// the longest palindromic
// subsequence in 'str'
int lps(string str)
{
    int n = str.size();
 
    // Create a table to store
    // results of subproblems
    int L[n][n];
 
    // Strings of length 1
    // are palindrome of length 1
    for (int i = 0; i < n; i++)
        L[i][i] = 1;
 
    // Build the table. Note that
    // the lower diagonal values
    // of table are useless and
    // not filled in the process.
    // c1 is length of substring
    for (int cl = 2; cl <= n; cl++)
    {
        for (int i = 0;
                 i < n - cl + 1; i++)
        {
            int j = i + cl - 1;
            if (str[i] == str[j] &&
                        cl == 2)
                L[i][j] = 2;
            else if (str[i] == str[j])
                L[i][j] = L[i + 1][j - 1] + 2;
            else
                L[i][j] = max(L[i][j - 1],
                            L[i + 1][j]);
        }
    }
 
    // length of longest
    // palindromic subseq
    return L[0][n - 1];
}
 
// function to calculate
// minimum number of deletions
int minimumNumberOfDeletions(string str)
{
    int n = str.size();
 
    // Find longest palindromic
    // subsequence
    int len = lps(str);
 
    // After removing characters
    // other than the lps, we
    // get palindrome.
    return (n - len);
}
 
// Driver Code
int main()
{
    string str = "geeksforgeeks";
    cout << "Minimum number of deletions = "
         << minimumNumberOfDeletions(str);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation to
// find minimum number of
// deletions to make a
// string palindromic
class GFG
{
    // Returns the length of
    // the longest palindromic
    // subsequence in 'str'
    static int lps(String str)
    {
        int n = str.length();
 
        // Create a table to store
        // results of subproblems
        int L[][] = new int[n][n];
 
        // Strings of length 1
        // are palindrome of length 1
        for (int i = 0; i < n; i++)
            L[i][i] = 1;
 
        // Build the table. Note
        // that the lower diagonal
        // values of table are useless
        // and not filled in the process.
        // c1 is length of substring
        for (int cl = 2; cl <= n; cl++)
        {
            for (int i = 0; i < n - cl + 1; i++)
            {
                int j = i + cl - 1;
                if (str.charAt(i) ==
                        str.charAt(j) && cl == 2)
                    L[i][j] = 2;
                else if (str.charAt(i) ==
                              str.charAt(j))
                    L[i][j] = L[i + 1][j - 1] + 2;
                else
                    L[i][j] = Integer.max(L[i][j - 1],
                                         L[i + 1][j]);
            }
        }
 
        // length of longest
        // palindromic subsequence
        return L[0][n - 1];
    }
 
    // function to calculate minimum
    // number of deletions
    static int minimumNumberOfDeletions(String str)
    {
        int n = str.length();
 
        // Find longest palindromic
        // subsequence
        int len = lps(str);
 
        // After removing characters
        // other than the lps, we get
        // palindrome.
        return (n - len);
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        System.out.println("Minimum number " +
                            "of deletions = "+
               minimumNumberOfDeletions(str));
    }
}
 
// This code is contributed by Sumit Ghosh

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation to find
# minimum number of deletions
# to make a string palindromic
  
# Returns the length of
# the longest palindromic
# subsequence in 'str'
def lps(str):
    n = len(str)
  
    # Create a table to store
    # results of subproblems
    L = [[0 for x in range(n)]for y in range(n)]
  
    # Strings of length 1
    # are palindrome of length 1
    for i in range(n):
        L[i][i] = 1
  
    # Build the table. Note that
    # the lower diagonal values
    # of table are useless and
    # not filled in the process.
    # c1 is length of substring
    for cl in range( 2, n+1):
        for i in range(n - cl + 1):
            j = i + cl - 1
            if (str[i] == str[j] and cl == 2):
                L[i][j] = 2
            elif (str[i] == str[j]):
                L[i][j] = L[i + 1][j - 1] + 2
            else:
                L[i][j] = max(L[i][j - 1],L[i + 1][j])
  
    # length of longest
    # palindromic subseq
    return L[0][n - 1]
  
# function to calculate
# minimum number of deletions
def minimumNumberOfDeletions( str):
 
    n = len(str)
  
    # Find longest palindromic
    # subsequence
    l = lps(str)
  
    # After removing characters
    # other than the lps, we
    # get palindrome.
    return (n - l)
  
# Driver Code
if __name__ == "__main__":
     
    str = "geeksforgeeks"
    print( "Minimum number of deletions = "
         , minimumNumberOfDeletions(str))

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation to find
// minimum number of deletions
// to make a string palindromic
using System;
 
class GFG
{
    // Returns the length of
    // the longest palindromic
    // subsequence in 'str'
    static int lps(String str)
    {
        int n = str.Length;
 
        // Create a table to store
        // results of subproblems
        int [,]L = new int[n, n];
 
        // Strings of length 1
        // are palindrome of length 1
        for (int i = 0; i < n; i++)
            L[i, i] = 1;
 
        // Build the table. Note
        // that the lower diagonal
        // values of table are useless
        // and not filled in the process.
        // c1 is length of substring
        for (int cl = 2; cl <= n; cl++)
        {
            for (int i = 0; i < n - cl + 1; i++)
            {
                int j = i + cl - 1;
                if (str[i] == str[j] && cl == 2)
                    L[i, j] = 2;
                else if (str[i] == str[j])
                    L[i, j] = L[i + 1, j - 1] + 2;
                else
                    L[i, j] = Math.Max(L[i, j - 1],
                                      L[i + 1, j]);
            }
        }
 
        // length of longest
        // palindromic subsequence
        return L[0, n - 1];
    }
 
    // function to calculate minimum
    // number of deletions
    static int minimumNumberOfDeletions(string str)
    {
        int n = str.Length;
 
        // Find longest palindromic
        // subsequence
        int len = lps(str);
 
        // After removing characters
        // other than the lps, we get
        // palindrome.
        return (n - len);
    }
 
    // Driver Code
    public static void Main()
    {
        string str = "geeksforgeeks";
        Console.Write("Minimum number of" +
                          " deletions = " +
            minimumNumberOfDeletions(str));
    }
}
 
// This code is contributed by nitin mittal.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation to find
// minimum number of deletions
// to make a string palindromic
 
// Returns the length of
// the longest palindromic
// subsequence in 'str'
function lps($str)
{
    $n = strlen($str);
 
    // Create a table to store
    // results of subproblems
    $L;
 
    // Strings of length 1
    // are palindrome of length 1
    for ($i = 0; $i < $n; $i++)
        $L[$i][$i] = 1;
 
    // Build the table. Note that
    // the lower diagonal values
    // of table are useless and
    // not filled in the process.
    // c1 is length of substring
    for ($cl = 2; $cl <= $n; $cl++)
    {
        for ( $i = 0;
              $i < $n -$cl + 1;
              $i++)
        {
            $j = $i + $cl - 1;
            if ($str[$i] == $str[$j] &&
                            $cl == 2)
                $L[$i][$j] = 2;
            else if ($str[$i] == $str[$j])
                $L[$i][$j] =
                        $L[$i + 1][$j - 1] + 2;
             
            else
                $L[$i][$j] = max($L[$i][$j - 1],
                                $L[$i + 1][$j]);
        }
    }
 
    // length of longest
    // palindromic subseq
    return $L[0][$n - 1];
}
 
// function to calculate minimum
// number of deletions
function minimumNumberOfDeletions($str)
{
    $n = strlen($str);
 
    // Find longest
    // palindromic subsequence
    $len = lps($str);
 
    // After removing characters
    // other than the lps, we get
    // palindrome.
    return ($n - $len);
}
 
// Driver Code
{
    $str = "geeksforgeeks";
    echo "Minimum number of deletions = ",
           minimumNumberOfDeletions($str);
    return 0;
}
 
// This code is contributed by nitin mittal.
?>

chevron_right


Output

Minimum number of deletions = 8

Time Complexity: O(n2)



Another Approach:

  • Take two indexes first as ‘i’ and last as a ‘j’
  • now compare the character at the index ‘i’ and ‘j’
  • if characters are equal, then 
    • recursively call the function by incrementing ‘i’ by ‘1’ and decrementing ‘j’ by ‘1’
  • else 
    • recursively call the two functions, the first increment ‘i’ by ‘1’ keeping ‘j’ constant, second decrement ‘j’ by ‘1’ keeping ‘i’ constant.
    • take a minimum of both and return by adding ‘1’

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for above approach
#include <iostream>
using namespace std;
 
// Function to return minimum
// Element between two values
int min(int x, int y)
{
  return (x < y) ? x : y;
}
 
// Utility function for calculating
// Minimum element to delete
int utility_fun_for_del(string str,
                          int i, int j)
{
    if (i >= j)
        return 0;
 
    // Condition to compare charecters
    if (str[i] == str[j])
    {
 
        // Recursive function call
        return utility_fun_for_del(str,
                                  i + 1, j - 1);
    }
 
    // Return value, increamenting by 1
    return 1 + min(utility_fun_for_del(str, i + 1, j),
                 utility_fun_for_del(str, i, j - 1));
}
 
// Function to calculate the minimum
// Element required to delete for
// Making string pelindrom
int min_ele_del(string str)
{
 
    // Utility function call
    return utility_fun_for_del(str, 0,
                               str.length() - 1);
}
 
// Driver code
int main()
{
    string str = "abefbac";
    cout << "Minimum element of deletions = "
         << min_ele_del(str) << endl;
    return 0;
}
 
// This code is contributed by MOHAMMAD MUDASSIR

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for above approach
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to return minimum
// Element between two values
public static int min(int x, int y)
{
    return (x < y) ? x : y;
}
  
// Utility function for calculating
// Minimum element to delete
public static int utility_fun_for_del(String str,
                                      int i, int j)
{
    if (i >= j)
        return 0;
  
    // Condition to compare charecters
    if (str.charAt(i) == str.charAt(j))
    {
         
        // Recursive function call
        return utility_fun_for_del(str,
                                   i + 1, j - 1);
    }
  
    // Return value, increamenting by 1
    return 1 + Math.min(utility_fun_for_del(str, i + 1, j),
                        utility_fun_for_del(str, i, j - 1));
}
  
// Function to calculate the minimum
// Element required to delete for
// Making string pelindrom
public static int min_ele_del(String str)
{
     
    // Utility function call
    return utility_fun_for_del(str, 0,
                               str.length() - 1);
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "abefbac";
     
    System.out.println("Minimum element of deletions = " +
                       min_ele_del(str));
}
}
 
// This code is contributed by divyeshrabadiya07

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for above approach
 
# Utility function for calculating
# Minimum element to delete
def utility_fun_for_del(Str, i, j):
     
    if (i >= j):
        return 0
 
    # Condition to compare charecters
    if (Str[i] == Str[j]):
         
        # Recursive function call
        return utility_fun_for_del(Str, i + 1,
                                        j - 1)
 
    # Return value, increamenting by 1
    # return minimum Element between two values   
    return (1 + min(utility_fun_for_del(Str, i + 1, j),
                    utility_fun_for_del(Str, i, j - 1)))
 
# Function to calculate the minimum
# Element required to delete for
# Making string pelindrom
def min_ele_del(Str):
 
    # Utility function call
    return utility_fun_for_del(Str, 0,
                           len(Str) - 1)
 
# Driver code
Str = "abefbac"
 
print("Minimum element of deletions =",
       min_ele_del(Str))
 
# This code is contributed by avanitrachhadiya2155

chevron_right


Output

Minimum element of deletions = 2

Approach: Top-down dynamic programming

We will first define the DP table and initialize it with -1 throughout the table. Follow the below approach now,

  1. Define the function transformation to calculate the Minimum number of deletions and insertions to transform one string into another
  2. We write the condition for  base cases
  3. Checking the wanted condition
  4. If the condition is satisfied we increment the value and store the value in the table
  5. If the recursive call is being solved earlier than we directly utilize the value from the table
  6. Else store the max transformation from the subsequence
  7. We will continue the process till we reach the base condition
  8. Return the DP [-1][-1]

Below is the implementation:

C++14

filter_none

edit
close

play_arrow

link
brightness_4
code

#include<bits/stdc++.h>
using namespace std;
 
int dp[2000][2000];
 
// Function defenation
int transformation(string s1, string s2,
                   int i, int j)
{
     
    // Base cases
    if (i >= (s1.size()) || j >= (s2.size()))
        return 0;
     
    // Checking the ndesired condition
    if (s1[i] == s2[j])
    {
         
        // If yes increment the cunt
        dp[i][j] = 1 + transformation(s1, s2, i + 1,
                                              j + 1);
    }
     
    // If no   
    if (dp[i][j] != -1)
    {
         
        // Return the value form the table
        return dp[i][j];
    }
     
    // Else store the max tranforamtion
    // from the subsequence
    else
        dp[i][j] = max(transformation(s1, s2, i, j + i),
                       transformation(s1, s2, i + 1, j));
     
    // Return the dp [-1][-1]   
    return dp[s1.size() - 1][s2.size() - 1];
}
 
// Driver code
int main()
{
    string s1 = "geeksforgeeks";
    string s2 = "geeks";
    int i = 0;
    int j = 0;
     
    // Initialize the array with -1
    memset(dp, -1, sizeof dp);
     
    cout << "MINIMUM NUMBER OF DELETIONS: "
         << (s1.size()) - transformation(s1, s2, 0, 0)
         << endl;
    cout << "MINIMUM NUMBER OF INSERTIONS: "
         << (s2.size()) - transformation(s1, s2, 0, 0)
         << endl;
    cout << ("LCS LENGTH: ")
         << transformation(s1, s2, 0, 0);
}
 
// This code is contributed by Stream_Cipher

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# function defenation
def transformation(s1,s2,i,j,dp):
     
     # base cases
    if i>=len(s1) or j>=len(s2):
        return 0
     
    # checking the ndesired condition
    if s1[i]==s2[j]:
         
        # if yes increment the cunt
        dp[i][j]=1+transformation(s1,s2,i+1,j+1,dp)
         
    # if no   
    if dp[i][j]!=-1:
         
        #return the value form the table
        return dp[i][j]
     
    # else store the max tranforamtion
    # from the subsequence
    else:
        dp[i][j]=max(transformation(s1,s2,i,j+i,dp),
                     transformation(s1,s2,i+1,j,dp))
         
    # return the dp [-1][-1]   
    return dp[-1][-1]
 
                      
 
s1 = "geeksforgeeks"
s2 = "geeks"
i=0
j=0
 
#initialize the array with -1
dp=[[-1 for _ in range(len(s1)+1)] for _ in range(len(s2)+1)]
print("MINIMUM NUMBER OF DELETIONS: ",
      len(s1)-transformation(s1,s2,0,0,dp),
      end=" ")
print("MINIMUM NUMBER OF INSERTIONS: ",
      len(s2)-transformation(s1,s2,0,0,dp),
      end=" " )
print("LCS LENGTH: ",transformation(s1,s2,0,0,dp))
 
#code contributed by saikumar kudikala

chevron_right


Output:

MINIMUM NUMBER OF DELETIONS:  8 MINIMUM NUMBER OF INSERTIONS:  0 LCS LENGTH:  5

Time Complexity: O(N^K)

Space Complexity: O(N)

This article is contributed by Ayush Jauhari

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up