Given a string containing characters as integers only. We need to delete all characters of this string in a minimum number of steps wherein in one step we can delete the substring which is a palindrome. After deleting a substring remaining parts are concatenated.
Examples:
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.
Approach 1 : (Recursion + Memoization) :
We can use recursion to solve the problem and memoization to optimize it. If the size of the string is one then only one operation is needed. If the first two characters are the same then call on the subproblem with i+2 as an index and add 1 to the returned answer. And another case we have to handle is if the i-th character got found in the string from i+2 to end index, i.e. in between i+2 to end index if anywhere we find the same character then we should add up the answer of two subproblems, one is – starting index + 1, i-1 and i+1, ending index (here, i is the index where we got the starting index character again.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int helper(string str, int si, int ei,
vector<vector< int > >& dp)
{
if (si > ei)
return 0;
if (ei - si + 1 == 1)
return 1;
if (dp[si][ei] != -1)
return dp[si][ei];
int op1 = 1e9, op2 = 1e9, op3 = 1e9;
op1 = 1 + helper(str, si + 1, ei, dp);
if (str[si] == str[si + 1])
op2 = 1 + helper(str, si + 2, ei, dp);
for ( int i = si + 2; i <= ei; i++) {
if (str[si] == str[i])
op3 = min(op3,
helper(str, si + 1, i - 1, dp)
+ helper(str, i + 1, ei, dp));
}
return dp[si][ei] = min({ op1, op2, op3 });
}
int minStepToDeleteString(string s)
{
int n = s.size();
vector<vector< int > > dp(n, vector< int >(n, -1));
return helper(s, 0, n - 1, dp);
}
int main()
{
string str = "2553432" ;
cout << minStepToDeleteString(str) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
static int [][] dp;
static int helper( char [] str, int si, int ei) {
if (si > ei) {
return 0 ;
}
if (ei - si + 1 == 1 ) {
return 1 ;
}
if (dp[si][ei] != - 1 ) {
return dp[si][ei];
}
int op1 = Integer.MAX_VALUE;
int op2 = Integer.MAX_VALUE;
int op3 = Integer.MAX_VALUE;
op1 = 1 + helper(str, si + 1 , ei);
if (str[si] == str[si + 1 ]) {
op2 = 1 + helper(str, si + 2 , ei);
}
for ( int i = si + 2 ; i <= ei; i++) {
if (str[si] == str[i]) {
op3 = Math.min(op3, helper(str, si + 1 , i - 1 ) + helper(str, i + 1 , ei));
}
}
dp[si][ei] = Math.min(op1, Math.min(op2, op3));
return dp[si][ei];
}
static int minStepToDeleteString(String s) {
int n = s.length();
dp = new int [n][n];
for ( int i = 0 ; i < n; i++) {
Arrays.fill(dp[i], - 1 );
}
return helper(s.toCharArray(), 0 , n - 1 );
}
public static void main(String[] args) {
String str = "2553432" ;
System.out.println(minStepToDeleteString(str));
}
}
|
Python3
def helper( str , si, ei, dp):
if si > ei:
return 0
if ei - si + 1 = = 1 :
return 1
if dp[si][ei] ! = - 1 :
return dp[si][ei]
op1 = 1e9
op2 = 1e9
op3 = 1e9
op1 = 1 + helper( str , si + 1 , ei, dp)
if str [si] = = str [si + 1 ]:
op2 = 1 + helper( str , si + 2 , ei, dp)
for i in range (si + 2 , ei + 1 ):
if str [si] = = str [i]:
op3 = min (op3, helper( str , si + 1 , i - 1 , dp) + helper( str , i + 1 , ei, dp))
dp[si][ei] = min (op1, op2, op3)
return dp[si][ei]
def minStepToDeleteString(s: str ) - > int :
n = len (s)
dp = [[ - 1 for i in range (n)] for j in range (n)]
return helper(s, 0 , n - 1 , dp)
if __name__ = = "__main__" :
str = "2553432"
print (minStepToDeleteString( str ))
|
Javascript
function helper( str, si, ei, dp)
{
if (si > ei)
return 0;
if (ei - si + 1 == 1)
return 1;
if (dp[si][ei] != -1)
return dp[si][ei];
let op1 = 1e9, op2 = 1e9, op3 = 1e9;
op1 = 1 + helper(str, si + 1, ei, dp);
if (str[si] == str[si + 1])
op2 = 1 + helper(str, si + 2, ei, dp);
for (let i = si + 2; i <= ei; i++) {
if (str[si] == str[i])
op3 = Math.min(op3,
helper(str, si + 1, i - 1, dp)
+ helper(str, i + 1, ei, dp));
}
return dp[si][ei] = Math.min( op1, Math.min(op2, op3 ));
}
function minStepToDeleteString(s)
{
let n = s.length;
let dp= new Array(n);
for (let i=0; i<n; i++)
dp[i]= new Array(n).fill(-1);
return helper(s, 0, n - 1, dp);
}
let str = "2553432" ;
console.log(minStepToDeleteString(str));
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG {
static int helper( string str, int si, int ei, int [,] dp)
{
if (si > ei)
return 0;
if (ei - si + 1 == 1)
return 1;
if (dp[si,ei] != -1)
return dp[si,ei];
int op1 = 1000000000, op2 = 1000000000, op3 = 1000000000;
op1 = 1 + helper(str, si + 1, ei, dp);
if (str[si] == str[si + 1])
op2 = 1 + helper(str, si + 2, ei, dp);
for ( int i = si + 2; i <= ei; i++) {
if (str[si] == str[i])
op3 = Math.Min(op3,
helper(str, si + 1, i - 1, dp)
+ helper(str, i + 1, ei, dp));
}
return dp[si,ei] = Math.Min(op1, Math.Min(op2, op3 ));
}
static int minStepToDeleteString( string s)
{
int n = s.Length;
int [,] dp= new int [n,n];
for ( int i=0; i<n; i++)
{
for ( int j=0; j<n; j++)
dp[i,j]=-1;
}
return helper(s, 0, n - 1, dp);
}
static public void Main()
{
string str = "2553432" ;
Console.Write(minStepToDeleteString(str));
}
}
|
Time & Space complexity corrected by RainX (Abhijit Roy, NIT AGARTALA)
Time complexity: O(n3)
Auxiliary Space: O(n3)
Approach 2 : (Dynamic Programming):
We can solve this problem using Dynamic programming. Let dp[i][j] denotes the number of steps it takes to delete the substring s[i, j]. Each character will be deleted alone or as part of some substring so in the first case we will delete the character itself and call subproblem (i+1, j). In the second case, we will iterate the overall occurrence of the current character on the right side, if K is the index of one such occurrence then the problem will reduce to two subproblems (i+1, K – 1) and (K+1, j). We can reach this subproblem (i+1, K-1) because we can just delete the same character and call for the mid-substring. We need to take care of a case when the first two characters are the same in that case we can directly reduce to the subproblem (i+2, j).
So after the above discussion of the relation among subproblems, we can write dp relation as follows,
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] )
The total time complexity of the above solution is O(n^3)
C++
#include <bits/stdc++.h>
using namespace std;
int minStepToDeleteString(string str)
{
int N = str.length();
int dp[N + 1][N + 1];
for ( int i = 0; i <= N; i++)
for ( int j = 0; j <= N; j++)
dp[i][j] = 0;
for ( int len = 1; len <= N; len++)
{
for ( int i = 0, j = len - 1; j < N; i++, j++)
{
if (len == 1)
dp[i][j] = 1;
else
{
dp[i][j] = 1 + dp[i + 1][j];
if (str[i] == str[i + 1])
dp[i][j] = min(1 + dp[i + 2][j], dp[i][j]);
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]);
}
}
}
return dp[0][N - 1];
}
int main()
{
string str = "2553432" ;
cout << minStepToDeleteString(str) << endl;
return 0;
}
|
Java
public class GFG
{
static int minStepToDeleteString(String str) {
int N = str.length();
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 ;
for ( int len = 1 ; len <= N; len++) {
for ( int i = 0 , j = len - 1 ; j < N; i++, j++) {
if (len == 1 )
dp[i][j] = 1 ;
else {
dp[i][j] = 1 + dp[i + 1 ][j];
if (str.charAt(i) == str.charAt(i + 1 ))
dp[i][j] = Math.min( 1 + dp[i + 2 ][j],
dp[i][j]);
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]);
}
}
}
return dp[ 0 ][N - 1 ];
}
public static void main(String args[]) {
String str = "2553432" ;
System.out.println(minStepToDeleteString(str));
}
}
|
Python 3
def minStepToDeleteString( str ):
N = len ( str )
dp = [[ 0 for x in range (N + 1 )]
for y in range (N + 1 )]
for l in range ( 1 , N + 1 ):
i = 0
j = l - 1
while j < N:
if (l = = 1 ):
dp[i][j] = 1
else :
dp[i][j] = 1 + dp[i + 1 ][j]
if ( str [i] = = str [i + 1 ]):
dp[i][j] = min ( 1 + dp[i + 2 ][j], dp[i][j])
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
return dp[ 0 ][N - 1 ]
if __name__ = = "__main__" :
str = "2553432"
print ( minStepToDeleteString( str ))
|
C#
using System;
class GFG {
static int minStepToDeleteString( string str)
{
int N = str.Length;
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;
for ( int len = 1; len <= N; len++) {
for ( int i = 0, j = len - 1; j < N; i++, j++)
{
if (len == 1)
dp[i,j] = 1;
else
{
dp[i,j] = 1 + dp[i + 1,j];
if (str[i] == str[i + 1])
dp[i,j] = Math.Min(1 + dp[i + 2,j],
dp[i,j]);
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]);
}
}
}
return dp[0,N - 1];
}
public static void Main()
{
string str = "2553432" ;
Console.Write(minStepToDeleteString(str));
}
}
|
PHP
<?php
function minStepToDeleteString( $str )
{
$N = strlen ( $str );
$dp [ $N + 1][ $N + 1] = array ( array ());
for ( $i = 0; $i <= $N ; $i ++)
for ( $j = 0; $j <= $N ; $j ++)
$dp [ $i ][ $j ] = 0;
for ( $len = 1; $len <= $N ; $len ++)
{
for ( $i = 0, $j = $len - 1;
$j < $N ; $i ++, $j ++)
{
if ( $len == 1)
$dp [ $i ][ $j ] = 1;
else
{
$dp [ $i ][ $j ] = 1 + $dp [ $i + 1][ $j ];
if ( $str [ $i ] == $str [ $i + 1])
$dp [ $i ][ $j ] = min(1 + $dp [ $i + 2][ $j ],
$dp [ $i ][ $j ]);
for ( $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 ]);
}
}
}
return $dp [0][ $N - 1];
}
$str = "2553432" ;
echo minStepToDeleteString( $str ), "\n" ;
?>
|
Javascript
<script>
function minStepToDeleteString(str)
{
let N = str.length;
let dp = new Array(N + 1);
for (let i = 0; i <= N; i++)
{
dp[i]= new Array(N+1);
for (let j = 0; j <= N; j++)
dp[i][j] = 0;
}
for (let len = 1; len <= N; len++) {
for (let i = 0, j = len - 1; j < N; i++, j++) {
if (len == 1)
dp[i][j] = 1;
else {
dp[i][j] = 1 + dp[i + 1][j];
if (str[i] == str[i+1])
dp[i][j] = Math.min(1 + dp[i + 2][j],
dp[i][j]);
for (let 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]);
}
}
}
return dp[0][N - 1];
}
let str = "2553432" ;
document.write(minStepToDeleteString(str));
</script>
|
Time & Space complexity corrected by RainX (Abhijit Roy, NIT AGARTALA)
Time complexity : O(n3)
Auxiliary Space : O(n3)