Minimize removal or insertions required to make two strings equal
Given two strings S and T, both of length N and S is an anagram of string T, the task is to convert string S to T by performing the following operations minimum number of times:
- Remove a character from either end.
- Insert a character at any position.
Print the count of the minimum number of operations required.
Examples:
Input: S = “qpmon”, T = “mnopq”
Output: 3
Explanation:
Operation 1: Remove ‘n’ from the end, and insert it at the second last position. The string S modifies to “qpmno”.
Operation 2: Remove ‘q’ from the start, and insert it at the last position. The string S modifies to “pmnoq”.
Operation 3: Remove ‘p’ from the start, and insert it at the second last position. The string S modifies to “mnopq” which is same as the desired string T.Input: S = “abab”, T = “baba”
Output: 1
Approach: The given problem can be solved by the following observation:
- It is required to find the length of the longest substring of A which is a subsequence in B. Let the length of that sub string be L.
- Then, the remaining characters can be inserted without disturbing the existing order.
- To conclude, the optimal answer will be equal to N – L.
Therefore, from the above observations, the minimum number of operations required is the difference between N and the length of the longest substring of the string A which is a subsequence in the string B.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find the longest substring // in string A which is a subsequence in B int findLongestSubstring( int posA, int posB, string& A, string& B, bool canSkip, int n, vector<vector<vector< int > > >& dp) { // If the indices are out of bounds if (posA >= n || posB >= n) { return 0; } // If an already computed subproblem occurred if (dp[posA][posB][canSkip] != -1) { return dp[posA][posB][canSkip]; } // Required answer if the all the // characters of A and B are the same int op1 = 0; // Required answer if there is no // substring A which is a // subsequence in B int op2 = 0; // Required answer if the current // character in B is skipped int op3 = 0; if (A[posA] == B[posB]) { op1 = 1 + findLongestSubstring( posA + 1, posB + 1, A, B, 0, n, dp); } if (canSkip) { op2 = findLongestSubstring( posA + 1, posB, A, B, canSkip, n, dp); } op3 = findLongestSubstring( posA, posB + 1, A, B, canSkip, n, dp); // The answer for the subproblem is // the maximum among the three return dp[posA][posB][canSkip] = max(op1, max(op2, op3)); } // Function to return the minimum strings // operations required to make two strings equal void minOperations(string A, string B, int N) { // Initialize the dp vector vector<vector<vector< int > > > dp( N, vector<vector< int > >( N, vector< int >(2, -1))); cout << N - findLongestSubstring( 0, 0, A, B, 1, N, dp); } // Driver Code int main() { string A = "abab" ; string B = "baba" ; int N = A.size(); minOperations(A, B, N); return 0; } |
Java
// Java program for the above approach import java.io.*; import java.util.*; class GFG { // Function to find the longest substring // in string A which is a subsequence in B static int findLongestSubstring( int posA, int posB, String A, String B, int canSkip, int n, int dp[][][]) { // If the indices are out of bounds if (posA >= n || posB >= n) { return 0 ; } // If an already computed subproblem occurred if (dp[posA][posB][canSkip] != - 1 ) { return dp[posA][posB][canSkip]; } // Required answer if the all the // characters of A and B are the same int op1 = 0 ; // Required answer if there is no // substring A which is a // subsequence in B int op2 = 0 ; // Required answer if the current // character in B is skipped int op3 = 0 ; if (A.charAt(posA) == B.charAt(posB)) { op1 = 1 + findLongestSubstring(posA + 1 , posB + 1 , A, B, 0 , n, dp); } if (canSkip == 1 ) { op2 = findLongestSubstring(posA + 1 , posB, A, B, canSkip, n, dp); } op3 = findLongestSubstring(posA, posB + 1 , A, B, canSkip, n, dp); // The answer for the subproblem is // the maximum among the three return dp[posA][posB][canSkip] = Math.max(op1, Math.max(op2, op3)); } // Function to return the minimum strings // operations required to make two strings equal static void minOperations(String A, String B, int N) { // Initialize the dp vector int [][][] dp = new int [N][N][ 2 ]; for ( int i = 0 ; i < N; i++) { for ( int j = 0 ; j < N; j++) { for ( int k = 0 ; k < 2 ; k++) { dp[i][j][k] = - 1 ; } } } System.out.println( N - findLongestSubstring( 0 , 0 , A, B, 1 , N, dp)); } // Driver Code public static void main(String[] args) { String A = "abab" ; String B = "baba" ; int N = A.length(); minOperations(A, B, N); } } // This code is contributed by Dharanendra L V |
Python3
# Python3 program for the above approach # Function to find the longest substring # in A which is a subsequence in B def findLongestSubstring(posA, posB, A, B, canSkip, n): global dp if (posA > = n or posB > = n): return 0 # If an already computed subproblem occurred if (dp[posA][posB][canSkip] ! = - 1 ): return dp[posA][posB][canSkip] # Required answer if the all the # characters of A and B are the same op1 = 0 # Required answer if there is no # subA which is a # subsequence in B op2 = 0 # Required answer if the current # character in B is skipped op3 = 0 if (A[posA] = = B[posB]): op1 = 1 + findLongestSubstring(posA + 1 , posB + 1 , A, B, 0 , n) if (canSkip): op2 = findLongestSubstring(posA + 1 , posB, A, B, canSkip, n) op3 = findLongestSubstring(posA, posB + 1 , A, B, canSkip, n) # The answer for the subproblem is # the maximum among the three dp[posA][posB][canSkip] = max (op1, max (op2, op3)) return dp[posA][posB][canSkip] # Function to return the minimum strings # operations required to make two strings equal def minOperations(A, B, N): print (N - findLongestSubstring( 0 , 0 , A, B, 1 , N)) # Driver Code if __name__ = = '__main__' : A = "abab" B = "baba" dp = [[[ - 1 , - 1 ] for i in range ( len (A))] for i in range ( len (A))] N = len (A) minOperations(A, B, N) # This code is contributed by mohit kumar 29. |
C#
// C# program for the above approach using System; class GFG { // Function to find the longest substring // in string A which is a subsequence in B static int findLongestSubstring( int posA, int posB, String A, String B, int canSkip, int n, int [, , ] dp) { // If the indices are out of bounds if (posA >= n || posB >= n) { return 0; } // If an already computed subproblem occurred if (dp[posA, posB, canSkip] != -1) { return dp[posA, posB, canSkip]; } // Required answer if the all the // characters of A and B are the same int op1 = 0; // Required answer if there is no // substring A which is a // subsequence in B int op2 = 0; // Required answer if the current // character in B is skipped int op3 = 0; if (A[posA] == B[posB]) { op1 = 1 + findLongestSubstring(posA + 1, posB + 1, A, B, 0, n, dp); } if (canSkip == 1) { op2 = findLongestSubstring(posA + 1, posB, A, B, canSkip, n, dp); } op3 = findLongestSubstring(posA, posB + 1, A, B, canSkip, n, dp); // The answer for the subproblem is // the maximum among the three return dp[posA, posB, canSkip] = Math.Max(op1, Math.Max(op2, op3)); } // Function to return the minimum strings // operations required to make two strings equal static void minOperations(String A, String B, int N) { // Initialize the dp vector int [, , ] dp = new int [N, N, 2]; for ( int i = 0; i < N; i++) { for ( int j = 0; j < N; j++) { for ( int k = 0; k < 2; k++) { dp[i, j, k] = -1; } } } Console.WriteLine( N - findLongestSubstring(0, 0, A, B, 1, N, dp)); } // Driver Code static public void Main () { String A = "abab" ; String B = "baba" ; int N = A.Length; minOperations(A, B, N); } } // This code is contributed by Dharanendra L V |
Javascript
<script> // JavaScript program for the above approach // Function to find the longest substring // in string A which is a subsequence in B function findLongestSubstring( posA, posB, A, B, canSkip, n, dp) { // If the indices are out of bounds if (posA >= n || posB >= n) { return 0; } // If an already computed subproblem occurred if (dp[posA][posB][canSkip] != -1) { return dp[posA][posB][canSkip]; } // Required answer if the all the // characters of A and B are the same var op1 = 0; // Required answer if there is no // substring A which is a // subsequence in B var op2 = 0; // Required answer if the current // character in B is skipped var op3 = 0; if (A[posA] == B[posB]) { op1 = 1 + findLongestSubstring( posA + 1, posB + 1, A, B, 0, n, dp); } if (canSkip) { op2 = findLongestSubstring( posA + 1, posB, A, B, canSkip, n, dp); } op3 = findLongestSubstring( posA, posB + 1, A, B, canSkip, n, dp); // The answer for the subproblem is // the maximum among the three return dp[posA][posB][canSkip] = Math.max(op1, Math.max(op2, op3)); } // Function to return the minimum strings // operations required to make two strings equal function minOperations(A, B, N) { // Initialize the dp vector var dp = Array.from(Array(N), ()=> Array(N)); for ( var i =0; i<N; i++) for ( var j =0; j<N; j++) dp[i][j] = new Array(2).fill(-1); document.write( N - findLongestSubstring( 0, 0, A, B, 1, N, dp)); } // Driver Code var A = "abab" ; var B = "baba" ; var N = A.length; minOperations(A, B, N); </script> |
1
Time Complexity: O(N2 )
Space Complexity: O(N2)
Please Login to comment...