📌  相关文章
📜  重复删除回文子串后删除字符串的最小步骤

📅  最后修改于: 2021-09-22 10:21:01             🧑  作者: Mango

给定一个仅包含整数字符的字符串。我们需要以最少的步骤删除该字符串的所有字符,其中一步我们可以删除回文子字符串。删除子串后,剩余部分被连接起来。

例子:

Input : s = “2553432”
Output : 2
We can delete all character of above string in
2 steps, first deleting the substring s[3, 5] “343”  
and then remaining string completely  s[0, 3] “2552”

Input : s = “1234”
Output : 4
We can delete all character of above string in 4 
steps only because each character need to be deleted 
separately. No substring of length 2 is a palindrome 
in above string.

我们可以使用动态规划来解决这个问题。令 dp[i][j] 表示删除子串 s[i, j] 所需的步数。每个字符都将被单独删除或作为某个子字符串的一部分被删除,因此在第一种情况下,我们将删除字符本身并调用子问题 (i+1, j)。在第二种情况下,我们将迭代右侧当前字符的整体出现,如果 K 是一个这样出现的索引,那么问题将减少到两个子问题 (i+1, K – 1) 和 (K+ 1, j)。我们可以解决这个子问题 (i+1, K-1),因为我们可以删除相同的字符并调用中间子串。我们需要处理前两个字符相同的情况,在这种情况下我们可以直接减少到子问题 (i+2, j)。
所以在上面讨论了子问题之间的关系之后,我们可以写出dp关系如下,

dp[i][j] = min(1 + dp[i+1][j],
          dp[i+1][K-1] + dp[K+1][j],  where s[i] == s[K]
          1 + dp[i+2][j] )

上述解决方案的总时间复杂度为 O(n^3)

C++
//  C++ program to find minimum step to delete a string
#include 
using namespace std;
 
/* method returns minimum step for deleting the string,
   where in one step a palindrome is removed */
int minStepToDeleteString(string str)
{
    int N = str.length();
 
    //  declare dp array and initialize it with 0s
    int dp[N + 1][N + 1];
    for (int i = 0; i <= N; i++)
        for (int j = 0; j <= N; j++)
            dp[i][j] = 0;
 
    // loop for substring length we are considering
    for (int len = 1; len <= N; len++)
    {
        // loop with two variables i and j, denoting
        // starting and ending of substrings
        for (int i = 0, j = len - 1; j < N; i++, j++)
        {
            // If substring length is 1, then 1 step
            // will be needed
            if (len == 1)
                dp[i][j] = 1;
            else
            {
                // delete the ith char individually
                // and assign result for subproblem (i+1,j)
                dp[i][j] = 1 + dp[i + 1][j];
 
                // if current and next char are same,
                // choose min from current and subproblem
                // (i+2,j)
                if (str[i] == str[i + 1])
                    dp[i][j] = min(1 + dp[i + 2][j], dp[i][j]);
 
                /*  loop over all right characters and suppose
                    Kth char is same as ith character then
                    choose minimum from current and two
                    substring after ignoring ith and Kth char */
                for (int K = i + 2; K <= j; K++)
                    if (str[i] == str[K])
                        dp[i][j] = min(dp[i+1][K-1] + dp[K+1][j],
                                                       dp[i][j]);
            }
        }
    }
 
    /* Uncomment below snippet to print actual dp tablex
    for (int i = 0; i < N; i++, cout << endl)
        for (int j = 0; j < N; j++)
            cout << dp[i][j] << " ";    */
 
    return dp[0][N - 1];
}
 
//  Driver code to test above methods
int main()
{
    string str = "2553432";
    cout << minStepToDeleteString(str) << endl;
    return 0;
}


Java
// Java program to find minimum step to
// delete a string
public class GFG
{                           
    /* method returns minimum step for deleting
       the string, where in one step a
       palindrome is removed
     */
    static int minStepToDeleteString(String str) {
        int N = str.length();
 
        // declare dp array and initialize it with 0s
        int[][] dp = new int[N + 1][N + 1];
        for (int i = 0; i <= N; i++)
            for (int j = 0; j <= N; j++)
                dp[i][j] = 0;
 
        // loop for substring length we are considering
        for (int len = 1; len <= N; len++) {
             
            // loop with two variables i and j, denoting
            // starting and ending of substrings
            for (int i = 0, j = len - 1; j < N; i++, j++) {
     
                // If substring length is 1, then 1 step
                // will be needed
                if (len == 1)
                    dp[i][j] = 1;
                     
                else {
                    // delete the ith char individually
                    // and assign result for
                    // subproblem (i+1,j)
                    dp[i][j] = 1 + dp[i + 1][j];
 
                    // if current and next char are same,
                    // choose min from current and
                    // subproblem (i+2, j)
                    if (str.charAt(i) == str.charAt(i + 1))
                        dp[i][j] = Math.min(1 + dp[i + 2][j],
                                               dp[i][j]);
 
                    /* loop over all right characters and
                      suppose Kth char is same as ith
                      character then choose minimum from
                      current and two substring after
                      ignoring ith and Kth char
                     */
                    for (int K = i + 2; K <= j; K++)
                        if (str.charAt(i) == str.charAt(K))
                            dp[i][j] = Math.min(
                                         dp[i + 1][K - 1] +
                                        dp[K + 1][j], dp[i][j]);
                }
            }
        }
 
        /* Uncomment below snippet to print actual dp tablex
          
           for (int i = 0; i < N; i++){
           System.out.println();
           for (int j = 0; j < N; j++)
           System.out.print(dp[i][j] + " ");
           }
            */
             
        return dp[0][N - 1];
    }
 
    // Driver code to test above methods
    public static void main(String args[]) {
        String str = "2553432";
        System.out.println(minStepToDeleteString(str));
    }
}
// This code is contributed by Sumit Ghosh


Python 3
# Python 3 program to find minimum
# step to delete a string
 
# method returns minimum step for
# deleting the string, where in one
# step a palindrome is removed
def minStepToDeleteString(str):
 
    N = len(str)
 
    # declare dp array and initialize
    # it with 0s
    dp = [[0 for x in range(N + 1)]
             for y in range(N + 1)]
 
    # loop for substring length
    # we are considering
    for l in range(1, N + 1):
         
        # loop with two variables i and j, denoting
        # starting and ending of substrings
        i = 0
        j = l - 1
        while j < N:
         
            # If substring length is 1,
            # then 1 step will be needed
            if (l == 1):
                dp[i][j] = 1
            else:
             
                # delete the ith char individually
                # and assign result for subproblem (i+1,j)
                dp[i][j] = 1 + dp[i + 1][j]
 
                # if current and next char are
                # same, choose min from current
                # and subproblem (i+2,j)
                if (str[i] == str[i + 1]):
                    dp[i][j] = min(1 + dp[i + 2][j], dp[i][j])
 
                ''' loop over all right characters and suppose
                    Kth char is same as ith character then
                    choose minimum from current and two
                    substring after ignoring ith and Kth char '''
                for K in range(i + 2, j + 1):
                    if (str[i] == str[K]):
                        dp[i][j] = min(dp[i + 1][K - 1] +
                                       dp[K + 1][j], dp[i][j])
                         
            i += 1
            j += 1
 
    # Uncomment below snippet to print
    # actual dp tablex
    # for (int i = 0; i < N; i++, cout << endl)
    # for (int j = 0; j < N; j++)
    #     cout << dp[i][j] << " ";
 
    return dp[0][N - 1]
 
# Driver Code
if __name__ == "__main__":
    str = "2553432"
    print( minStepToDeleteString(str))
 
# This code is contributed by ChitraNayal


C#
// C# program to find minimum step to
// delete a string
using System;
 
class GFG {   
     
    /* method returns minimum step for deleting
    the string, where in one step a
    palindrome is removed */
    static int minStepToDeleteString(string str)
    {
        int N = str.Length;
 
        // declare dp array and initialize it
        // with 0s
        int [,]dp = new int[N + 1,N + 1];
         
        for (int i = 0; i <= N; i++)
            for (int j = 0; j <= N; j++)
                dp[i,j] = 0;
 
        // loop for substring length we are
        // considering
        for (int len = 1; len <= N; len++) {
             
            // loop with two variables i and j,
            // denoting starting and ending of
            // substrings
            for (int i = 0, j = len - 1; j < N; i++, j++)
            {
     
                // If substring length is 1, then 1
                // step will be needed
                if (len == 1)
                    dp[i,j] = 1;
                     
                else
                {
                    // delete the ith char individually
                    // and assign result for
                    // subproblem (i+1,j)
                    dp[i,j] = 1 + dp[i + 1,j];
 
                    // if current and next char are same,
                    // choose min from current and
                    // subproblem (i+2, j)
                    if (str[i] == str[i + 1])
                        dp[i,j] = Math.Min(1 + dp[i + 2,j],
                                                  dp[i,j]);
 
                    /* loop over all right characters and
                    suppose Kth char is same as ith
                    character then choose minimum from
                    current and two substring after
                    ignoring ith and Kth char
                    */
                    for (int K = i + 2; K <= j; K++)
                        if (str[i] == str[K])
                            dp[i,j] = Math.Min(
                                        dp[i + 1,K - 1] +
                                     dp[K + 1,j], dp[i,j]);
                }
            }
        }
 
        /* Uncomment below snippet to print actual dp tablex
         
        for (int i = 0; i < N; i++){
        System.out.println();
        for (int j = 0; j < N; j++)
        System.out.print(dp[i][j] + " ");
        } */
             
        return dp[0,N - 1];
    }
 
    // Driver code to test above methods
    public static void Main()
    {
        string str = "2553432";
        Console.Write(minStepToDeleteString(str));
    }
}
 
// This code is contributed by nitin mittal


PHP


Javascript


输出:

2

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程