给定一个仅包含整数字符的字符串。我们需要以最少的步骤删除该字符串的所有字符,而在第一步中,我们可以删除作为回文的子字符串。删除子字符串后,其余部分将串联在一起。
例子:
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
输出:
2