📜  形成回文的最小插入数| DP-28

📅  最后修改于: 2021-05-04 08:54:19             🧑  作者: Mango

给定字符串str ,任务是找到要插入的最少字符数,以将其转换为回文。
在进一步介绍之前,让我们看几个例子:

  • ab:所需插入次数为1,即b ab
  • aa:所需插入次数为0,即aa
  • abcd:所需的插入数为3,即dcb abcd
  • abcda:要求的插入次数为2,即dc bcda,它与子字符串bcd(为什么?)中的插入次数相同。
  • abcde:所需插入的次数为4,即edcb abcde

令输入字符串为str [l……h] 。该问题可以分为三个部分:

  1. 在子字符串str [l + 1,…….h]中找到最小插入数。
  2. 在子字符串str [l…….h-1]中找到最小插入数。
  3. 在子字符串str [l + 1……h-1]中找到最小插入数。

递归方法:字符串str [l…..h]中的最小插入次数可以表示为:

  • 如果str [l]等于str [h],则minInsertions(str [l + 1…..h-1])
  • min(minInsertions(str [l…..h-1]),minInsertions(str [l + 1….h]))+ 1否则

下面是上述方法的实现:

C++
// A Naive recursive program to find minimum
// number insertions needed to make a string
// palindrome
#include
using namespace std;
 
 
// Recursive function to find 
// minimum number of insertions
int 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 subrpoblem(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 code
int main()
{
    char str[] = "geeks";
    cout << findMinInsertions(str, 0, strlen(str) - 1);
    return 0;
}
 
// This code is contributed by
// Akanksha Rai


C
// A Naive recursive program to find minimum
// number insertions needed to make a string
// palindrome
#include 
#include 
#include 
 
// A utility function to find minimum of two numbers
int min(int a, int b)
{  return a < b ? a : b; }
 
// Recursive function to find minimum number of
// insertions
int 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 subrpoblem(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 functions
int main()
{
    char str[] = "geeks";
    printf("%d", findMinInsertions(str, 0, strlen(str)-1));
    return 0;
}


Java
// A Naive recursive Java program to find minimum
// number insertions needed to make a string
// palindrome
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 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 subrpoblem(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


Python 3
# A Naive recursive program to find minimum
# number insertions needed to make a string
# palindrome
import sys
 
# Recursive function to find minimum
# number of insertions
def 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 subrpoblem(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 Code
if __name__ == "__main__":
     
    str = "geeks"
    print(findMinInsertions(str, 0, len(str) - 1))
 
# This code is contributed by ita_c


C#
// A Naive recursive C# program
// to find minimum number
// insertions needed to make
// a string palindrom
using 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 subrpoblem(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


Javascript


C++
// A Dynamic Programming based program to find
// minimum number insertions needed to make a
// string palindrome
#include 
using namespace std;
 
 
// A DP function to find minimum
// number of insertions
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[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 Code
int main()
{
    char str[] = "geeks";
    cout << findMinInsertionsDP(str, strlen(str));
    return 0;
}
 
// This is code is contributed by rathbhupendra


C
// A Dynamic Programming based program to find
// minimum number insertions needed to make a
// string palindrome
#include 
#include 
 
// A utility function to find minimum of two integers
int min(int a, int b)
{   return a < b ? a : b;  }
 
// A DP function to find minimum number of insertions
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[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;
}


Java
// A Java solution for Dynamic Programming
// based program to find minimum number
// insertions needed to make a string
// palindrome
import java.util.Arrays;
 
class GFG
{
    // A DP function to find minimum number
    // of insersions
    static int findMinInsertionsDP(char str[], int n)
    {
        // Create a table of size n*n. table[i][j]
        // will store minumum 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


Python3
# A Dynamic Programming based program to
# find minimum number insertions needed
# to make a str1ing palindrome
 
# A utility function to find minimum
# of two integers
def Min(a, b):
    return min(a, b)
 
# A DP function to find minimum number
# of insertions
def 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 Code
str1 = "geeks"
print(findMinInsertionsDP(str1, len(str1)))
 
# This code is contributed by
# Mohit kumar 29


C#
// A C# solution for Dynamic Programming
// based program to find minimum number
// insertions needed to make a string
// palindrome
using System;
 
class GFG
{
    // A DP function to find minimum number
    // of insersions
    static int findMinInsertionsDP(char []str, int n)
    {
        // Create a table of size n*n. table[i][j]
        // will store minumum 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


Javascript


C++
// An LCS based program to find minimum number
// insertions needed to make a string palindrome
#include 
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
// insertions
int 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 code
int main()
{
    string str = "geeks";
    cout << findMinInsertionsLCS(str, str.length());
    return 0;
}
 
// This code is contributed by rathbhupendra


C
// An LCS based program to find minimum number
// insertions needed to make a string palindrome
#include
#include 
 
/* 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
// insertions
int 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 functions
int main()
{
    char str[] = "geeks";
    printf("%d", findMinInsertionsLCS(str, strlen(str)));
    return 0;
}


Java
// An LCS based Java program to find minimum
// number insertions needed to make a string
// palindrome
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.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 insersions
    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


Python3
# 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 for
details 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 insersions
def 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


C#
// An LCS based C# program to find minimum
// number insertions needed to make a string
// palindrome
using 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 insersions
    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


输出:

3

基于动态编程的解决方案
如果我们仔细观察上述方法,我们会发现它表现出重叠的子问题。
假设我们要查找字符串“ 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………………….

粗体字的子字符串表示要终止的递归,并且递归树不能从此处开始。相同颜色的子字符串表示重叠的子问题。
如何重用子问题的解决方案?记忆化技术用于避免类似的子问题调用。我们可以创建一个表来存储子问题的结果,以便在再次遇到相同子问题时可以直接使用它们。
下表代表字符串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

如何填表?
桌子应该以对角线的形式填充。对于字符串abcde,0….4,应按以下顺序填充表:

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)

下面是上述方法的实现:

C++

// A Dynamic Programming based program to find
// minimum number insertions needed to make a
// string palindrome
#include 
using namespace std;
 
 
// A DP function to find minimum
// number of insertions
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[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 Code
int main()
{
    char str[] = "geeks";
    cout << findMinInsertionsDP(str, strlen(str));
    return 0;
}
 
// This is code is contributed by rathbhupendra

C

// A Dynamic Programming based program to find
// minimum number insertions needed to make a
// string palindrome
#include 
#include 
 
// A utility function to find minimum of two integers
int min(int a, int b)
{   return a < b ? a : b;  }
 
// A DP function to find minimum number of insertions
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[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;
}

Java

// A Java solution for Dynamic Programming
// based program to find minimum number
// insertions needed to make a string
// palindrome
import java.util.Arrays;
 
class GFG
{
    // A DP function to find minimum number
    // of insersions
    static int findMinInsertionsDP(char str[], int n)
    {
        // Create a table of size n*n. table[i][j]
        // will store minumum 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

Python3

# A Dynamic Programming based program to
# find minimum number insertions needed
# to make a str1ing palindrome
 
# A utility function to find minimum
# of two integers
def Min(a, b):
    return min(a, b)
 
# A DP function to find minimum number
# of insertions
def 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 Code
str1 = "geeks"
print(findMinInsertionsDP(str1, len(str1)))
 
# This code is contributed by
# Mohit kumar 29

C#

// A C# solution for Dynamic Programming
// based program to find minimum number
// insertions needed to make a string
// palindrome
using System;
 
class GFG
{
    // A DP function to find minimum number
    // of insersions
    static int findMinInsertionsDP(char []str, int n)
    {
        // Create a table of size n*n. table[i][j]
        // will store minumum 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

Java脚本


输出:

3

时间复杂度: O(N ^ 2)
辅助空间: O(N ^ 2)
另一个动态编程解决方案(最长公共子序列问题的变化)
查找最长插入的问题也可以使用最长公共子序列(LCS)问题解决。如果我们找到字符串的LCS及其相反的字符,就知道可以形成回文数的最大字符数。我们需要插入剩余字符。以下是步骤。

  1. 找出输入字符串的LCS长度及其反方向。令长度为“ l”。
  2. 所需的最小插入次数是输入字符串的长度减去“ l”。

下面是上述方法的实现:

C++

// An LCS based program to find minimum number
// insertions needed to make a string palindrome
#include 
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
// insertions
int 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 code
int main()
{
    string str = "geeks";
    cout << findMinInsertionsLCS(str, str.length());
    return 0;
}
 
// This code is contributed by rathbhupendra

C

// An LCS based program to find minimum number
// insertions needed to make a string palindrome
#include
#include 
 
/* 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
// insertions
int 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 functions
int main()
{
    char str[] = "geeks";
    printf("%d", findMinInsertionsLCS(str, strlen(str)));
    return 0;
}

Java

// An LCS based Java program to find minimum
// number insertions needed to make a string
// palindrome
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.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 insersions
    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

Python3

# 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 for
details 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 insersions
def 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

C#

// An LCS based C# program to find minimum
// number insertions needed to make a string
// palindrome
using 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 insersions
    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

输出:

3