Minimum insertions to form a palindrome | DP-28 - GeeksforGeeks

25 Feb, 2022
Given string str, the task is to find the minimum number of characters to be inserted to convert it to a palindrome.
Before we go further, let us understand with a few examples: 
ab: Number of insertions required is 1 i.e. bab
aa: Number of insertions required is 0 i.e. aa
abcd: Number of insertions required is 3 i.e. dcbabcd
abcda: Number of insertions required is 2 i.e. adcbcda which is the same as the number of insertions in the substring bcd(Why?).
abcde: Number of insertions required is 4 i.e. edcbabcde
Let the input string be str[l......h]. The problem can be broken down into three parts:  
Find the minimum number of insertions in the substring str[l+1,.......h].Find the minimum number of insertions in the substring str[l.......h-1].Find the minimum number of insertions in the substring str[l+1......h-1].
Find the minimum number of insertions in the substring str[l+1,.......h].
Find the minimum number of insertions in the substring str[l.......h-1].
Find the minimum number of insertions in the substring str[l+1......h-1].
Recursive Approach: The minimum number of insertions in the string str[l.....h] can be given as:  
minInsertions(str[l+1.....h-1]) if str[l] is equal to str[h]
min(minInsertions(str[l.....h-1]), minInsertions(str[l+1.....h])) + 1 otherwise
Below is the implementation of the above approach:  
C++
C
Java
Python 3
C#
Javascript
// A Naive recursive program to find minimum// number insertions needed to make a string// palindrome#include<bits/stdc++.h>using namespace std;  // Recursive function to find // minimum number of insertionsint findMinInsertions(char str[], int l, int h){    // Base Cases    if (l > h) return INT_MAX;    if (l == h) return 0;    if (l == h - 1) return (str[l] == str[h])? 0 : 1;     // Check if the first and last characters are    // same. On the basis of the comparison result,    // decide which subproblem(s) to call    return (str[l] == str[h])?                    findMinInsertions(str, l + 1, h - 1):                    (min(findMinInsertions(str, l, h - 1),                    findMinInsertions(str, l + 1, h)) + 1);} // Driver codeint main(){    char str[] = "geeks";    cout << findMinInsertions(str, 0, strlen(str) - 1);    return 0;} // This code is contributed by// Akanksha Rai
// A Naive recursive program to find minimum// number insertions needed to make a string// palindrome#include <stdio.h>#include <limits.h>#include <string.h> // A utility function to find minimum of two numbersint min(int a, int b){  return a < b ? a : b; } // Recursive function to find minimum number of// insertionsint findMinInsertions(char str[], int l, int h){    // Base Cases    if (l > h) return INT_MAX;    if (l == h) return 0;    if (l == h - 1) return (str[l] == str[h])? 0 : 1;     // Check if the first and last characters are    // same. On the basis of the comparison result,    // decide which subproblem(s) to call    return (str[l] == str[h])?                     findMinInsertions(str, l + 1, h - 1):                     (min(findMinInsertions(str, l, h - 1),                     findMinInsertions(str, l + 1, h)) + 1);} // Driver program to test above functionsint main(){    char str[] = "geeks";    printf("%d", findMinInsertions(str, 0, strlen(str)-1));    return 0;}
// A Naive recursive Java program to find minimum// number insertions needed to make a string// palindromeclass GFG {     // Recursive function to find minimum number    // of insertions    static int findMinInsertions(char str[], int l,                                             int h)    {        // Base Cases        if (l > h) return Integer.MAX_VALUE;        if (l == h) return 0;        if (l == h - 1) return (str[l] == str[h])? 0 : 1;         // Check if the first and last characters        // are same. On the basis of the  comparison        // result, decide which subproblem(s) to call        return (str[l] == str[h])?            findMinInsertions(str, l + 1, h - 1):            (Integer.min(findMinInsertions(str, l, h - 1),            findMinInsertions(str, l + 1, h)) + 1);    }     // Driver program to test above functions    public static void main(String args[])    {        String str= "geeks";        System.out.println(findMinInsertions(str.toCharArray(),                                          0, str.length()-1));    }}// This code is contributed by Sumit Ghosh
# A Naive recursive program to find minimum# number insertions needed to make a string# palindromeimport sys # Recursive function to find minimum# number of insertionsdef findMinInsertions(str, l, h):     # Base Cases    if (l > h):        return sys.maxsize    if (l == h):        return 0    if (l == h - 1):        return 0 if(str[l] == str[h]) else 1     # Check if the first and last characters are    # same. On the basis of the comparison result,    # decide which subproblem(s) to call         if(str[l] == str[h]):        return findMinInsertions(str, l + 1, h - 1)    else:        return (min(findMinInsertions(str, l, h - 1),                    findMinInsertions(str, l + 1, h)) + 1) # Driver Codeif __name__ == "__main__":         str = "geeks"    print(findMinInsertions(str, 0, len(str) - 1)) # This code is contributed by ita_c
// A Naive recursive C# program// to find minimum number// insertions needed to make// a string palindromeusing System; class GFG{    // Recursive function to    // find minimum number of    // insertions    static int findMinInsertions(char []str,                                 int l, int h)    {        // Base Cases        if (l > h) return int.MaxValue;        if (l == h) return 0;        if (l == h - 1)            return (str[l] == str[h])? 0 : 1;         // Check if the first and        // last characters are same.        // On the basis of the        // comparison result, decide        // which subproblem(s) to call        return (str[l] == str[h])?                findMinInsertions(str,                                  l + 1, h - 1):                (Math.Min(findMinInsertions(str, l,                                            h - 1),                          findMinInsertions(str, l +                                        1, h)) + 1);    }         // Driver Code    public static void Main()    {        string str= "geeks";        Console.WriteLine(findMinInsertions(str.ToCharArray(),                                            0, str.Length - 1));    }} // This code is contributed by Sam007
<script> // A Naive recursive JavaScript program to find minimum// number insertions needed to make a string// palindrome     // Recursive function to find minimum number    // of insertions    function findMinInsertions(str,l,h)    {        // Base Cases        if (l > h)            return Number.MAX_VALUE;                 if (l == h)            return 0;                 if (l == h - 1)            return (str[l] == str[h])? 0 : 1;                 // Check if the first and last characters        // are same. On the basis of the  comparison        // result, decide which subproblem(s) to call        return (str[l] == str[h]) ?        findMinInsertions(str, l + 1, h - 1) :        (Math.min(findMinInsertions(str, l, h - 1),        findMinInsertions(str, l + 1, h)) + 1)           }         // Driver program to test above functions    let str= "geeks";    document.write(findMinInsertions(str,0, str.length-1));              // This code is contributed by rag2127     </script>
Output: 
3
Dynamic Programming based Solution If we observe the above approach carefully, we can find that it exhibits overlapping subproblems. Suppose we want to find the minimum number of insertions in string “abcde”:  
                      abcde
            /       |      \
           /        |        \
           bcde         abcd       bcd  <- case 3 is discarded as str[l] != str[h]
       /   |   \       /   |   \
      /    |    \     /    |    \
     cde   bcd  cd   bcd abc bc
   / | \  / | \ /|\ / | \
de cd d cd bc c......................
The substrings in bold show that the recursion is to be terminated and the recursion tree cannot originate from there. Substring in the same color indicates overlapping subproblems.
How to re-use solutions of subproblems? The memorization technique is used to avoid similar subproblem recalls. We can create a table to store the results of subproblems so that they can be used directly if the same subproblem is encountered again.The below table represents the stored values for the string abcde. 
a b c d e
----------
0 1 2 3 4
0 0 1 2 3 
0 0 0 1 2 
0 0 0 0 1 
0 0 0 0 0
How to fill the table? The table should be filled in a diagonal fashion. For the string abcde, 0....4, the following should be ordered in which the table is filled:
Gap = 1: (0, 1) (1, 2) (2, 3) (3, 4)

Gap = 2: (0, 2) (1, 3) (2, 4)

Gap = 3: (0, 3) (1, 4)

Gap = 4: (0, 4)
Below is the implementation of the above approach: 
C++
C
Java
Python3
C#
Javascript
// A Dynamic Programming based program to find// minimum number insertions needed to make a// string palindrome#include <bits/stdc++.h>using namespace std;  // A DP function to find minimum// number of insertionsint findMinInsertionsDP(char str[], int n){    // Create a table of size n*n. table[i][j]    // will store minimum number of insertions    // needed to convert str[i..j] to a palindrome.    int table[n][n], l, h, gap;     // Initialize all table entries as 0    memset(table, 0, sizeof(table));     // Fill the table    for (gap = 1; gap < n; ++gap)        for (l = 0, h = gap; h < n; ++l, ++h)            table[l][h] = (str[l] == str[h])?                        table[l + 1][h - 1] :                        (min(table[l][h - 1],                             table[l + 1][h]) + 1);     // Return minimum number of insertions    // for str[0..n-1]    return table[0][n - 1];} // Driver Codeint main(){    char str[] = "geeks";    cout << findMinInsertionsDP(str, strlen(str));    return 0;} // This is code is contributed by rathbhupendra
// A Dynamic Programming based program to find// minimum number insertions needed to make a// string palindrome#include <stdio.h>#include <string.h> // A utility function to find minimum of two integersint min(int a, int b){   return a < b ? a : b;  } // A DP function to find minimum number of insertionsint findMinInsertionsDP(char str[], int n){    // Create a table of size n*n. table[i][j]    // will store minimum number of insertions    // needed to convert str[i..j] to a palindrome.    int table[n][n], l, h, gap;     // Initialize all table entries as 0    memset(table, 0, sizeof(table));     // Fill the table    for (gap = 1; gap < n; ++gap)        for (l = 0, h = gap; h < n; ++l, ++h)            table[l][h] = (str[l] == str[h])?                          table[l+1][h-1] :                          (min(table[l][h-1],                           table[l+1][h]) + 1);     // Return minimum number of insertions for    // str[0..n-1]    return table[0][n-1];} // Driver program to test above function.int main(){    char str[] = "geeks";    printf("%d", findMinInsertionsDP(str, strlen(str)));    return 0;}
// A Java solution for Dynamic Programming// based program to find minimum number// insertions needed to make a string// palindromeimport java.util.Arrays; class GFG{    // A DP function to find minimum number    // of insertions    static int findMinInsertionsDP(char str[], int n)    {        // Create a table of size n*n. table[i][j]        // will store minimum number of insertions        // needed to convert str[i..j] to a palindrome.        int table[][] = new int[n][n];        int l, h, gap;         // Fill the table        for (gap = 1; gap < n; ++gap)        for (l = 0, h = gap; h < n; ++l, ++h)            table[l][h] = (str[l] == str[h])?                           table[l+1][h-1] :                          (Integer.min(table[l][h-1],                                 table[l+1][h]) + 1);         // Return minimum number of insertions        // for str[0..n-1]        return table[0][n-1];    }     // Driver program to test above function.    public static void main(String args[])    {        String str = "geeks";        System.out.println(        findMinInsertionsDP(str.toCharArray(), str.length()));    }}// This code is contributed by Sumit Ghosh
# A Dynamic Programming based program to# find minimum number insertions needed# to make a string palindrome # A utility function to find minimum# of two integersdef Min(a, b):    return min(a, b) # A DP function to find minimum number# of insertionsdef findMinInsertionsDP(str1, n):     # Create a table of size n*n. table[i][j]    # will store minimum number of insertions    # needed to convert str1[i..j] to a palindrome.    table = [[0 for i in range(n)]                for i in range(n)]    l, h, gap = 0, 0, 0     # Fill the table    for gap in range(1, n):        l = 0        for h in range(gap, n):            if str1[l] == str1[h]:                table[l][h] = table[l + 1][h - 1]            else:                table[l][h] = (Min(table[l][h - 1],                                   table[l + 1][h]) + 1)            l += 1     # Return minimum number of insertions    # for str1[0..n-1]    return table[0][n - 1]; # Driver Codestr1 = "geeks"print(findMinInsertionsDP(str1, len(str1))) # This code is contributed by# Mohit kumar 29
// A C# solution for Dynamic Programming// based program to find minimum number// insertions needed to make a string// palindromeusing System; class GFG{    // A DP function to find minimum number    // of insertions    static int findMinInsertionsDP(char []str, int n)    {        // Create a table of size n*n. table[i][j]        // will store minimum number of insertions        // needed to convert str[i..j] to a palindrome.        int [,]table = new int[n, n];        int l, h, gap;         // Fill the table        for (gap = 1; gap < n; ++gap)        for (l = 0, h = gap; h < n; ++l, ++h)            table[l, h] = (str[l] == str[h])?                        table[l+1, h-1] :                        (Math.Min(table[l, h-1],                                table[l+1, h]) + 1);         // Return minimum number of insertions        // for str[0..n-1]        return table[0, n-1];    }     // Driver code    public static void Main()    {        String str = "geeks";        Console.Write(        findMinInsertionsDP(str.ToCharArray(), str.Length));    }} // This code is contributed by Rajput-Ji
<script> // A Javascript solution for Dynamic Programming// based program to find minimum number// insertions needed to make a string// palindrome          // A DP function to find minimum number    // of insertions    function findMinInsertionsDP(str,n)    {        // Create a table of size n*n. table[i][j]        // will store minimum number of insertions        // needed to convert str[i..j] to a palindrome.                 let table=new Array(n);        for(let i=0;i<n;i++)        {            table[i]=new Array(n);        }                          for(let i=0;i<n;i++)        {            for(let j=0;j<n;j++)            {                table[i][j]=0;            }        }                          let  l=0, h=0, gap=0;        // Fill the table        for (gap = 1; gap < n; gap++)        {            for (l = 0, h = gap; h < n; l++, h++)            {                                                  table[l][h] = (str[l] == str[h]) ? table[l+1][h-1] : (Math.min(table[l][h-1],table[l+1][h]) + 1);                             }        }        // Return minimum number of insertions        // for str[0..n-1]        return table[0][n - 1];    }    // Driver program to test above function.    let str = "geeks";    document.write(findMinInsertionsDP(str, str.length));         // This code is contributed by avanitrachhadiya2155     </script>
Output: 
3
Time complexity: O(N^2) Auxiliary Space: O(N^2)
Another Dynamic Programming Solution (Variation of Longest Common Subsequence Problem) The problem of finding minimum insertions can also be solved using Longest Common Subsequence (LCS) Problem. If we find out the LCS of string and its reverse, we know how many maximum characters can form a palindrome. We need to insert the remaining characters. Following are the steps. 
Find the length of LCS of the input string and its reverse. Let the length be ‘l’.The minimum number of insertions needed is the length of the input string minus ‘l’.
Find the length of LCS of the input string and its reverse. Let the length be ‘l’.
The minimum number of insertions needed is the length of the input string minus ‘l’.
Below is the implementation of the above approach:  
C++
C
Java
Python3
C#
Javascript
// An LCS based program to find minimum number// insertions needed to make a string palindrome#include <bits/stdc++.h>using namespace std;   // Returns length of LCS for X[0..m-1], Y[0..n-1].int lcs( string X, string Y, int m, int n ){    int L[m+1][n+1];    int i, j;         /* Following steps build L[m+1][n+1] in bottom        up fashion. Note that L[i][j] contains length        of LCS of X[0..i-1] and Y[0..j-1] */    for (i = 0; i <= m; i++)    {        for (j = 0; j <= n; j++)        {        if (i == 0 || j == 0)            L[i][j] = 0;             else if (X[i - 1] == Y[j - 1])            L[i][j] = L[i - 1][j - 1] + 1;             else            L[i][j] = max(L[i - 1][j], L[i][j - 1]);        }    }         /* L[m][n] contains length of LCS for X[0..n-1]        and Y[0..m-1] */    return L[m][n];} void reverseStr(string& str){    int n = str.length();     // Swap character starting from two    // corners    for (int i = 0; i < n / 2; i++)        swap(str[i], str[n - i - 1]);} // LCS based function to find minimum number of// insertionsint findMinInsertionsLCS(string str, int n){    // Creata another string to store reverse of 'str'    string rev = "";    rev = str;    reverseStr(rev);         // The output is length of string minus length of lcs of    // str and it reverse    return (n - lcs(str, rev, n, n));} // Driver codeint main(){    string str = "geeks";    cout << findMinInsertionsLCS(str, str.length());    return 0;} // This code is contributed by rathbhupendra
// An LCS based program to find minimum number// insertions needed to make a string palindrome#include<stdio.h>#include <string.h> /* Utility function to get max of 2 integers */int max(int a, int b){   return (a > b)? a : b; } /* Returns length of LCS for X[0..m-1], Y[0..n-1].   See http://goo.gl/bHQVP for details of this   function */int lcs( char *X, char *Y, int m, int n ){   int L[m+1][n+1];   int i, j;    /* Following steps build L[m+1][n+1] in bottom      up fashion. Note that L[i][j] contains length      of LCS of X[0..i-1] and Y[0..j-1] */   for (i=0; i<=m; i++)   {     for (j=0; j<=n; j++)     {       if (i == 0 || j == 0)         L[i][j] = 0;        else if (X[i-1] == Y[j-1])         L[i][j] = L[i-1][j-1] + 1;        else         L[i][j] = max(L[i-1][j], L[i][j-1]);     }   }    /* L[m][n] contains length of LCS for X[0..n-1]     and Y[0..m-1] */   return L[m][n];} // LCS based function to find minimum number of// insertionsint findMinInsertionsLCS(char str[], int n){   // Creata another string to store reverse of 'str'   char rev[n+1];   strcpy(rev, str);   strrev(rev);    // The output is length of string minus length of lcs of   // str and it reverse   return (n - lcs(str, rev, n, n));} // Driver program to test above functionsint main(){    char str[] = "geeks";    printf("%d", findMinInsertionsLCS(str, strlen(str)));    return 0;}
// An LCS based Java program to find minimum// number insertions needed to make a string// palindromeclass GFG{    /* Returns length of LCS for X[0..m-1],       Y[0..n-1]. See http://goo.gl/bHQVP for       details of this function */    static int lcs( String X, String Y, int m, int n )    {        int L[][] = new int[m+1][n+1];        int i, j;         /* Following steps build L[m+1][n+1] in           bottom up fashion. Note that L[i][j]           contains length of LCS of X[0..i-1]           and Y[0..j-1] */        for (i=0; i<=m; i++)        {            for (j=0; j<=n; j++)            {                if (i == 0 || j == 0)                    L[i][j] = 0;                 else if (X.charAt(i-1) == Y.charAt(j-1))                    L[i][j] = L[i-1][j-1] + 1;                 else                    L[i][j] = Integer.max(L[i-1][j], L[i][j-1]);            }        }         /* L[m][n] contains length of LCS for           X[0..n-1] and Y[0..m-1] */        return L[m][n];    }     // LCS based function to find minimum number    // of insertions    static int findMinInsertionsLCS(String str, int n)    {        // Using StringBuffer to reverse a String        StringBuffer sb = new StringBuffer(str);        sb.reverse();        String revString = sb.toString();         // The output is length of string minus        // length of lcs of str and it reverse        return (n - lcs(str, revString , n, n));    }     // Driver program to test above functions    public static void main(String args[])    {        String str = "geeks";        System.out.println(        findMinInsertionsLCS(str, str.length()));    }}// This code is contributed by Sumit Ghosh
# An LCS based Python3 program to find minimum# number insertions needed to make a string# palindrome """ Returns length of LCS for X[0..m-1],Y[0..n-1]. See http://goo.gl/bHQVP fordetails of this function """def lcs(X, Y, m, n) :     L = [[0 for i in range(n + 1)] for j in range(m + 1)]     """ Following steps build L[m + 1, n + 1] in    bottom up fashion. Note that L[i, j]    contains length of LCS of X[0..i - 1]    and Y[0..j - 1] """    for i in range(m + 1) :            for j in range(n + 1) :                  if (i == 0 or j == 0) :                L[i][j] = 0             elif (X[i - 1] == Y[j - 1]) :                L[i][j] = L[i - 1][j - 1] + 1            else :                L[i][j] = max(L[i - 1][j], L[i][j - 1])     """ L[m,n] contains length of LCS for    X[0..n-1] and Y[0..m-1] """    return L[m][n]     # LCS based function to find minimum number# of insertionsdef findMinInsertionsLCS(Str, n) :     # Using charArray to reverse a String    charArray = list(Str)    charArray.reverse()    revString = "".join(charArray)         # The output is length of string minus    # length of lcs of str and it reverse    return (n - lcs(Str, revString , n, n)) # Driver code Str = "geeks"print(findMinInsertionsLCS(Str,len(Str))) # This code is contributed by divyehrabadiya07
// An LCS based C# program to find minimum// number insertions needed to make a string// palindromeusing System; class GFG{    /* Returns length of LCS for X[0..m-1],    Y[0..n-1]. See http://goo.gl/bHQVP for    details of this function */    static int lcs( string X, string Y, int m, int n )    {        int[,] L = new int[m + 1, n + 1];        int i, j;         /* Following steps build L[m+1,n+1] in        bottom up fashion. Note that L[i,j]        contains length of LCS of X[0..i-1]        and Y[0..j-1] */        for (i = 0; i <= m; i++)        {            for (j = 0; j <= n; j++)            {                if (i == 0 || j == 0)                    L[i, j] = 0;                 else if (X[i - 1] == Y[j - 1])                    L[i, j] = L[i - 1, j - 1] + 1;                 else                    L[i, j] = Math.Max(L[i - 1, j], L[i, j - 1]);            }        }         /* L[m,n] contains length of LCS for        X[0..n-1] and Y[0..m-1] */        return L[m,n];    }     // LCS based function to find minimum number    // of insertions    static int findMinInsertionsLCS(string str, int n)    {        // Using charArray to reverse a String        char[] charArray = str.ToCharArray();        Array.Reverse(charArray);        string revString = new string(charArray);         // The output is length of string minus        // length of lcs of str and it reverse        return (n - lcs(str, revString , n, n));    }     // Driver code    static void Main()    {        string str = "geeks";        Console.WriteLine(findMinInsertionsLCS(str,str.Length));    }} // This code is contributed by mits
<script>// An LCS based Javascript program to find minimum// number insertions needed to make a string// palindrome         /* Returns length of LCS for X[0..m-1],       Y[0..n-1]. See http://goo.gl/bHQVP for       details of this function */    function lcs(X, Y, m, n)    {        let L = new Array(m+1);        for(let i = 0; i < m + 1; i++)        {            L[i] = new Array(n+1);            for(let j = 0; j < n + 1; j++)            {                L[i][j] = 0;            }        }                 let i, j;          /* Following steps build L[m+1][n+1] in           bottom up fashion. Note that L[i][j]           contains length of LCS of X[0..i-1]           and Y[0..j-1] */        for (i = 0; i <= m; i++)        {            for (j = 0; j <= n; j++)            {                if (i == 0 || j == 0)                    L[i][j] = 0;                  else if (X[i - 1] == Y[j - 1])                    L[i][j] = L[i - 1][j - 1] + 1;                  else                    L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);            }        }          /* L[m][n] contains length of LCS for           X[0..n-1] and Y[0..m-1] */        return L[m][n];    }         // LCS based function to find minimum number    // of insertions    function findMinInsertionsLCS(str, n)    {        let revString = str.split('').reverse().join('');                 // The output is length of string minus        // length of lcs of str and it reverse        return (n - lcs(str, revString , n, n));             }         // Driver program to test above functions    let str = "geeks";    document.write(findMinInsertionsLCS(str, str.length));         // This code is contributed by unknown2108</script>
Output: 
3
Time complexity: O(N^2) Auxiliary Space: O(N^2) 
Related Article : Minimum number of Appends needed to make a string palindromeThis article is compiled by Aashish Barnwal. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
Sam007
ukasp
mohit kumar 29
Rajput-Ji
Akanksha_Rai
rathbhupendra
Mithun Kumar
nandishwar001
divyeshrabadiya07
rag2127
avanitrachhadiya2155
unknown2108
simmytarika5
surindertarika1234
kumaripunam984122
Amazon
Google
palindrome
Dynamic Programming
Strings
Amazon
Google
Strings
Dynamic Programming
palindrome
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Floyd Warshall Algorithm | DP-16
Matrix Chain Multiplication | DP-8
Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)
Edit Distance | DP-5
Overlapping Subproblems Property in Dynamic Programming | DP-1
Write a program to reverse an array or string
Reverse a string in Java
Write a program to print all permutations of a given string
C++ Data Types
Check for Balanced Brackets in an expression (well-formedness) using Stack