Transform an Empty String to a Given String
Last Updated :
05 Mar, 2024
Given a string s1 and an empty string s2, you have to transform the empty string s2 to given string s1 using the given moves. In one move, you can create a sequence of identical characters on string s2 or overwrite any substring with a new character on string s2. The task is to minimize the number of moves to transform string s2 to s1.
Example:
Input: s1 = “aaaddd”, s2 = “”
Output: 2
Explanation: Write “aaa” first and then write “ddd”.
Input: s1 = “aca”, s2 = “”
Output: 2
Explanation: Write “aaa” first and then write “c” from the second place of the string, which will cover the existing character ‘a’.
Approach:
This problem can be simplified by breaking it down into smaller parts using the Divide and Conquer strategy. We continue to divide the string ‘s1’ until we get substrings of 1 or 2 characters, which act as our base case. We create a dynamic programming (DP) table ‘dp’, where dp[i][j] represents the minimum number of operations needed to write the substring from the i-th to the j-th character in ‘s’ (both inclusive).
Base Case: For a single character (a substring of length 1), we only need one operation to write it. Hence, dp[i][i] is set to 1 for all ‘i’.
Recursive Formula: We then find the minimum number of operations for substrings of length 2, 3, and so on, up to the length of the entire string.
For each substring length, we iterate over all possible starting (i) and ending (j) points of that substring. To compute dp[i][j], we iterate over all possible ‘k’ from ‘i’ to ‘j-1’ (inclusive). For each ‘k’, we try to find the minimum number of operations by combining the minimum operations required to write s1[i…k] and s1[k+1…j].
Final Answer: The solution to the problem will be stored in dp[0][n-1], where ‘n’ is the length of the string.
Steps-by-step approach:
- Set n to the length of the string s1 and create a 2D vector dp of size n x n, initialized with zeros.
- Iterate from the end of the string to the beginning (from n-1 to 0).
- For each character at position i, set dp[i][i] to 1 as a base case.
- For each position i, iterate from i+1 to n-1 (inclusive).
- Initialize dp[i][j] to INT_MAX.
- Iterate through partition points k from i to j.
- Calculate the minimum operations for writing s1[i…k] and s1[k+1…j].
- If s1[i] and s1[j] are the same, decrement minOperations by 1.
- Update dp[i][j] with the minimum operations for writing s1[i…j].
- Return dp[0][n – 1], representing the minimum operations needed to write the entire string s1[0…n-1].
Below is the implementation of the above approach:
C++
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int minOperation(string s)
{
int n = s.length();
vector<vector< int > > dp(n, vector< int >(n, 0));
for ( int i = n - 1; i >= 0; --i) {
dp[i][i] = 1;
for ( int j = i + 1; j < n; ++j) {
dp[i][j] = INT_MAX;
for ( int k = i; k < j; ++k) {
int minOperations = dp[i][k] + dp[k + 1][j];
if (s[i] == s[j])
minOperations--;
dp[i][j] = min(dp[i][j], minOperations);
}
}
}
return dp[0][n - 1];
}
int main()
{
string S1 = "aabca" , S2 = "" ;
cout << minOperation(S1);
return 0;
}
|
Java
public class MinOperation {
static int minOperation(String s) {
int n = s.length();
int [][] dp = new int [n][n];
for ( int i = n - 1 ; i >= 0 ; --i) {
dp[i][i] = 1 ;
for ( int j = i + 1 ; j < n; ++j) {
dp[i][j] = Integer.MAX_VALUE;
for ( int k = i; k < j; ++k) {
int minOperations = dp[i][k] + dp[k + 1 ][j];
if (s.charAt(i) == s.charAt(j))
minOperations--;
dp[i][j] = Math.min(dp[i][j], minOperations);
}
}
}
return dp[ 0 ][n - 1 ];
}
public static void main(String[] args) {
String S1 = "aabca" ;
System.out.println(minOperation(S1));
}
}
|
Python
def minOperation(s):
n = len (s)
dp = [[ 0 ] * n for _ in range (n)]
for i in range (n - 1 , - 1 , - 1 ):
dp[i][i] = 1
for j in range (i + 1 , n):
dp[i][j] = float ( 'inf' )
for k in range (i, j):
minOperations = dp[i][k] + dp[k + 1 ][j]
if s[i] = = s[j]:
minOperations - = 1
dp[i][j] = min (dp[i][j], minOperations)
return dp[ 0 ][n - 1 ]
if __name__ = = "__main__" :
S1 = "aabca"
print (minOperation(S1))
|
C#
using System;
public class MinOperation {
static int CalculateMinOperation( string s)
{
int n = s.Length;
int [, ] dp = new int [n, n];
for ( int i = n - 1; i >= 0; --i) {
dp[i, i] = 1;
for ( int j = i + 1; j < n; ++j) {
dp[i, j] = int .MaxValue;
for ( int k = i; k < j; ++k) {
int minOperations
= dp[i, k] + dp[k + 1, j];
if (s[i] == s[j])
minOperations--;
dp[i, j]
= Math.Min(dp[i, j], minOperations);
}
}
}
return dp[0, n - 1];
}
public static void Main( string [] args)
{
string S1 = "aabca" ;
Console.WriteLine(CalculateMinOperation(S1));
}
}
|
Javascript
function minOperation(s) {
const n = s.length;
const dp = Array.from({ length: n }, () => Array(n).fill(0));
for (let i = n - 1; i >= 0; i--) {
dp[i][i] = 1;
for (let j = i + 1; j < n; j++) {
dp[i][j] = Infinity;
for (let k = i; k < j; k++) {
let minOperations = dp[i][k] + dp[k + 1][j];
if (s[i] === s[j]) {
minOperations--;
}
dp[i][j] = Math.min(dp[i][j], minOperations);
}
}
}
return dp[0][n - 1];
}
const S1 = "aabca" ;
console.log(minOperation(S1));
|
Time Complexity: O(n^3), where n is length of given string.
Auxiliary Space: O(n*n)
Share your thoughts in the comments
Please Login to comment...