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++
| //  C++ program to find minimum step to delete a string#include <bits/stdc++.h>usingnamespacestd;/* method returns minimum step for deleting the string,   where in one step a palindrome is removed */inthelper(string str, intsi, intei,           vector<vector<int> >& dp){    // if the string is empty    // need no operation    if(si > ei)        return0;    // string length one    // need one operation    if(ei - si + 1 == 1)        return1;    // if already calculated    if(dp[si][ei] != -1)        returndp[si][ei];    // to consider three options    intop1 = 1e9, op2 = 1e9, op3 = 1e9;    // delete first char and call    // on the smaller subproblem    op1 = 1 + helper(str, si + 1, ei, dp);    // first two characters are same    if(str[si] == str[si + 1])        op2 = 1 + helper(str, si + 2, ei, dp);    // found another index where the    // character is same as si-th character    for(inti = 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 the minimum b/w three options    returndp[si][ei] = min({ op1, op2, op3 });}intminStepToDeleteString(string s){    intn = s.size();    // dp table to remove repeatations    vector<vector<int> > dp(n, vector<int>(n, -1));    // passing starting and ending index    returnhelper(s, 0, n - 1, dp);}// Driver Codeintmain(){    string str = "2553432";    cout << minStepToDeleteString(str) << endl;    return0;}// this code is contributed by rajdeep999 | 
Java
| // Java program to find minimum step to delete a stringimportjava.util.*;publicclassMain {    staticint[][] dp;    staticinthelper(char[] str, intsi, intei) {        // if the string is empty        // need no operation        if(si > ei) {            return0;        }        // string length one        // need one operation        if(ei - si + 1== 1) {            return1;        }        // if already calculated        if(dp[si][ei] != -1) {            returndp[si][ei];        }        // to consider three options        intop1 = Integer.MAX_VALUE;        intop2 = Integer.MAX_VALUE;        intop3 = Integer.MAX_VALUE;        // delete first char and call        // on the smaller subproblem        op1 = 1+ helper(str, si + 1, ei);        // first two characters are same        if(str[si] == str[si + 1]) {            op2 = 1+ helper(str, si + 2, ei);        }        // found another index where the        // character is same as si-th character        for(inti = 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));            }        }        // return the minimum between three options        dp[si][ei] = Math.min(op1, Math.min(op2, op3));        returndp[si][ei];    }    staticintminStepToDeleteString(String s) {        intn = s.length();        // dp table to remove repetitions        dp = newint[n][n];        for(inti = 0; i < n; i++) {            Arrays.fill(dp[i], -1);        }        // passing starting and ending index        returnhelper(s.toCharArray(), 0, n - 1);    }    publicstaticvoidmain(String[] args) {        String str = "2553432";        System.out.println(minStepToDeleteString(str));    }} | 
Python3
| #  Pythom program to find minimum step to delete a stringdefhelper(str, si, ei, dp):    # if the string is empty    # need no operation    ifsi > ei:        return0        # string length one    # need one operation    ifei -si +1==1:        return1        # if already calculated    ifdp[si][ei] !=-1:        returndp[si][ei]    # to consider three options    op1 =1e9    op2 =1e9    op3 =1e9    # delete first char and call    # on the smaller subproblem    op1 =1+helper(str, si +1, ei, dp)    # first two characters are same    ifstr[si] ==str[si +1]:        op2 =1+helper(str, si +2, ei, dp)    # found another index where the    # character is same as si-th character    fori inrange(si+2, ei+1):        ifstr[si] ==str[i]:            op3 =min(op3, helper(str, si +1, i -1, dp) +helper(str, i +1, ei, dp))    # return the minimum b/w three options    dp[si][ei] =min(op1, op2, op3)    returndp[si][ei]defminStepToDeleteString(s:str) -> int:    n =len(s)    # dp table to remove repeatations    dp =[[-1fori inrange(n)] forj inrange(n)]    # passing starting and ending index    returnhelper(s, 0, n -1, dp)# Driver Codeif__name__ =="__main__":    str="2553432"    print(minStepToDeleteString(str))# This code is contributed by Potta Lokesh | 
Javascript
| //  Javascript 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 */functionhelper( str, si, ei, dp){    // if the string is empty    // need no operation    if(si > ei)        return0;    // string length one    // need one operation    if(ei - si + 1 == 1)        return1;    // if already calculated    if(dp[si][ei] != -1)        returndp[si][ei];    // to consider three options    let op1 = 1e9, op2 = 1e9, op3 = 1e9;    // delete first char and call    // on the smaller subproblem    op1 = 1 + helper(str, si + 1, ei, dp);    // first two characters are same    if(str[si] == str[si + 1])        op2 = 1 + helper(str, si + 2, ei, dp);    // found another index where the    // character is same as si-th character    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 the minimum b/w three options    returndp[si][ei] = Math.min( op1, Math.min(op2, op3 ));}functionminStepToDeleteString(s){    let n = s.length;    // dp table to remove repeatations    let dp=newArray(n);    for(let i=0; i<n; i++)        dp[i]=newArray(n).fill(-1);    // passing starting and ending index    returnhelper(s, 0, n - 1, dp);}// Driver Codelet str = "2553432";console.log(minStepToDeleteString(str)); | 
C#
| //  C# program to find minimum step to delete a stringusingSystem;usingSystem.Linq;usingSystem.Collections.Generic;classGFG {    /* method returns minimum step for deleting the string,       where in one step a palindrome is removed */    staticinthelper(stringstr, intsi, intei,int[,] dp)    {            // if the string is empty        // need no operation        if(si > ei)            return0;            // string length one        // need one operation        if(ei - si + 1 == 1)            return1;            // if already calculated        if(dp[si,ei] != -1)            returndp[si,ei];            // to consider three options        intop1 = 1000000000, op2 = 1000000000, op3 = 1000000000;            // delete first char and call        // on the smaller subproblem        op1 = 1 + helper(str, si + 1, ei, dp);            // first two characters are same        if(str[si] == str[si + 1])            op2 = 1 + helper(str, si + 2, ei, dp);            // found another index where the        // character is same as si-th character        for(inti = 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 the minimum b/w three options        returndp[si,ei] = Math.Min(op1, Math.Min(op2, op3 ));    }        staticintminStepToDeleteString(strings)    {        intn = s.Length;            // dp table to remove repeatations        int[,] dp=newint[n,n];        for(inti=0; i<n; i++)        {            for(intj=0; j<n; j++)                dp[i,j]=-1;        }            // passing starting and ending index        returnhelper(s, 0, n - 1, dp);    }        // Driver Code    staticpublicvoidMain()    {        stringstr = "2553432";        Console.Write(minStepToDeleteString(str));    }} | 
2
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++
| //  C++ program to find minimum step to delete a string#include <bits/stdc++.h>usingnamespacestd;/* method returns minimum step for deleting the string,   where in one step a palindrome is removed */intminStepToDeleteString(string str){    intN = str.length();    //  declare dp array and initialize it with 0s    intdp[N + 1][N + 1];    for(inti = 0; i <= N; i++)        for(intj = 0; j <= N; j++)            dp[i][j] = 0;    // loop for substring length we are considering    for(intlen = 1; len <= N; len++)    {        // loop with two variables i and j, denoting        // starting and ending of substrings        for(inti = 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(intK = 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] << " ";    */    returndp[0][N - 1];}//  Driver code to test above methodsintmain(){    string str = "2553432";    cout << minStepToDeleteString(str) << endl;    return0;} | 
Java
| // Java program to find minimum step to // delete a stringpublicclassGFG {                                /* method returns minimum step for deleting       the string, where in one step a       palindrome is removed     */    staticintminStepToDeleteString(String str) {        intN = str.length();        // declare dp array and initialize it with 0s        int[][] dp = newint[N + 1][N + 1];        for(inti = 0; i <= N; i++)            for(intj = 0; j <= N; j++)                dp[i][j] = 0;        // loop for substring length we are considering        for(intlen = 1; len <= N; len++) {                        // loop with two variables i and j, denoting            // starting and ending of substrings            for(inti = 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(intK = 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] + " ");           }            */                    returndp[0][N - 1];    }    // Driver code to test above methods    publicstaticvoidmain(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 defminStepToDeleteString(str):    N =len(str)    # declare dp array and initialize     # it with 0s    dp =[[0forx inrange(N +1)]             fory inrange(N +1)]    # loop for substring length    # we are considering    forl inrange(1, N +1):                # loop with two variables i and j, denoting        # starting and ending of substrings        i =0        j =l -1        whilej < 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 '''                forK inrange(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] << " ";     returndp[0][N -1]# Driver Codeif__name__ =="__main__":    str="2553432"    print( minStepToDeleteString(str))# This code is contributed by ChitraNayal | 
C#
| // C# program to find minimum step to // delete a stringusingSystem;classGFG {            /* method returns minimum step for deleting    the string, where in one step a    palindrome is removed */    staticintminStepToDeleteString(stringstr)    {        intN = str.Length;        // declare dp array and initialize it         // with 0s        int[,]dp = newint[N + 1,N + 1];                for(inti = 0; i <= N; i++)            for(intj = 0; j <= N; j++)                dp[i,j] = 0;        // loop for substring length we are        // considering        for(intlen = 1; len <= N; len++) {                        // loop with two variables i and j,            // denoting starting and ending of             // substrings            for(inti = 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(intK = 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] + " ");        } */                    returndp[0,N - 1];    }    // Driver code to test above methods    publicstaticvoidMain()     {        stringstr = "2553432";        Console.Write(minStepToDeleteString(str));    }}// This code is contributed by nitin mittal | 
PHP
| <?php// PHP 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 */functionminStepToDeleteString($str){    $N= strlen($str);    // declare dp array and initialize     // it with 0s    $dp[$N+ 1][$N+ 1] = array(array());    for($i= 0; $i<= $N; $i++)        for($j= 0; $j<= $N; $j++)            $dp[$i][$j] = 0;    // loop for substring length we    // are considering    for($len= 1; $len<= $N; $len++)    {        // loop with two variables i and j, denoting        // starting and ending of substrings        for($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($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$str= "2553432";echominStepToDeleteString($str), "\n";// This code is contributed by ajit.?> | 
Javascript
| <script>// Java Script 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     */    functionminStepToDeleteString(str)    {        let N = str.length;          // declare dp array and initialize it with 0s        let dp = newArray(N + 1);        for(let i = 0; i <= N; i++)        {            dp[i]=newArray(N+1);            for(let j = 0; j <= N; j++)                dp[i][j] = 0;          }        // loop for substring length we are considering        for(let len = 1; len <= N; len++) {                          // loop with two variables i and j, denoting            // starting and ending of substrings            for(let 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(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]);                }            }        }          /* 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] + " ");           }            */                      returndp[0][N - 1];    }        // Driver code to test above methods    let str = "2553432";    document.write(minStepToDeleteString(str));        // This code is contributed by avanitrachhadiya2155</script> | 
2
Time & Space complexity corrected by RainX (Abhijit Roy, NIT AGARTALA)
Time complexity : O(n3) 
Auxiliary Space : O(n3)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    







