Open In App

Transform string A into B by deleting characters from ends and reinserting at any position

Given two strings A and B that are anagrams of each other, the task is to convert A to B if possible in minimum number of operations. An operation is defined as removing either the first or the last character in A and inserting it back anywhere in the string. 

Examples:



Input: A = “edacb”,  B = “abcde”
Output : 3
Explanation : The three operations are:

  • We can remove “b” and insert it after “a” to get “edabc”
  • We can remove “e” and insert it after “c” to get “dabce”
  • We can remove “d” and insert it after “c” to get “abcde”

Input : A = “xyz”, B = “xyz” 
Output : 0
Explanation : String A is equal to String B so no operation is required.



 

Approach: The approach is based on Dynamic Programming and Longest Common Subsequence (LCS)

Intuition:

Algorithm: This problem can be solved with Dynamic Programming much like the classic LCS (longest common subsequence) problem. See the comments in the code for the precise DP state. The main difference from LCS is that we cannot include dp[i-1][j] in dp[i][j], since that would break the contiguity of the A-substring.

Below is the implementation of the above approach :

// C++ implementation of the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find min operations
int minOperations(string A, string B)
{
    // dp[i][j] = length of longest
    //(contiguous) suffix of A[0..i]
    // that is a subsequence of B[0..j]
    int dp[1001][1001];
 
    // r = maximum value over all
    // dp[i][j] computed so far
    int r = 0;
 
    for (int i = 0; i <= A.size(); ++i) {
        for (int j = 0; j <= B.size(); ++j) {
 
            dp[i][j] = 0;
 
            if (i && j) {
 
                // any suffix of A[0..i]
                // which is a subsequence of B[0..j]
                // is also a subsequence of B[0..j-1]...
                dp[i][j] = dp[i][j - 1];
 
                // or, if last character matches (i.e.
                // A[i-1] == B[j-1]), and then the rest
                // of the suffix is a suffix of
                // A[0..i-1] and a subsequence of B[j-1]
                if (A[i - 1] == B[j - 1]) {
 
                    dp[i][j] = max(
                        dp[i][j],
                        1 + dp[i - 1][j - 1]);
                    r = max(r, dp[i][j]);
                }
            }
        }
    }
 
    // r = the length of the
    // longest (contiguous) substring
    // of A that is a subsequence of B
    return A.size() - r;
}
 
// Driver code
int main()
{
    string A = "edacb";
    string B = "abcde";
    cout << minOperations(A, B);
    return 0;
}

                    
// Java implementation of the above approach
import java.util.*;
public class GFG {
 
    // Function to find min operations
    static int minOperations(String A, String B)
    {
       
        // dp[i][j] = length of longest
        //(contiguous) suffix of A[0..i]
        // that is a subsequence of B[0..j]
        int[][] dp = new int[1001][1001];
 
        // r = maximum value over all
        // dp[i][j] computed so far
        int r = 0;
 
        for (int i = 0; i <= A.length(); ++i) {
            for (int j = 0; j <= B.length(); ++j) {
 
                dp[i][j] = 0;
 
                if (i > 0 && j > 0) {
 
                    // any suffix of A[0..i]
                    // which is a subsequence of B[0..j]
                    // is also a subsequence of B[0..j-1]...
                    dp[i][j] = dp[i][j - 1];
 
                    // or, if last character matches (i.e.
                    // A[i-1] == B[j-1]), and then the rest
                    // of the suffix is a suffix of
                    // A[0..i-1] and a subsequence of B[j-1]
                    if (A.charAt(i - 1)
                        == B.charAt(j - 1)) {
 
                        dp[i][j] = Math.max(
                            dp[i][j], 1 + dp[i - 1][j - 1]);
                        r = Math.max(r, dp[i][j]);
                    }
                }
            }
        }
 
        // r = the length of the
        // longest (contiguous) substring
        // of A that is a subsequence of B
        return A.length() - r;
    }
 
    // Driver code
    public static void main(String args[])
    {
        String A = "edacb";
        String B = "abcde";
        System.out.println(minOperations(A, B));
    }
}
 
// This code is contributed by Smim Hossain Mondal.

                    
<script>
 
# python3 implementation of the above approach
 
# Function to find min operations
def minOperations(A, B) :
 
    # dp[i][j] = length of longest
    # (contiguous) suffix of A[0..i]
    # that is a subsequence of B[0..j]
    dp = [[ 0 for _ in range(1001)] for _ in range(1001) ]
 
    # r = maximum value over all
    # dp[i][j] computed so far
    r = 0
 
    for i in range(0, len(A) + 1) :
        for j in range(0, len(B) + 1) :
 
            dp[i][j] = 0
 
            if (i and j) :
 
                # any suffix of A[0..i]
                # which is a subsequence of B[0..j]
                # is also a subsequence of B[0..j-1]...
                dp[i][j] = dp[i][j - 1]
 
                # or, if last character matches (i.e.
                # A[i-1] == B[j-1]), and then the rest
                # of the suffix is a suffix of
                # A[0..i-1] and a subsequence of B[j-1]
                if (A[i - 1] == B[j - 1]) :
 
                    dp[i][j] = max(
                        dp[i][j],
                        1 + dp[i - 1][j - 1])
                    r = max(r, dp[i][j])
                 
 
    # r = the length of the
    # longest (contiguous) substring
    # of A that is a subsequence of B
    return len(A) - r
 
 
# Driver code
if __name__ == "__main__" :
 
    A = "edacb"
    B = "abcde"
    print(minOperations(A, B))
     
    # This code is contributed by rakeshsahni

                    
// C# implementation of the above approach
using System;
class GFG {
 
  // Function to find min operations
  static int minOperations(string A, string B)
  {
    // dp[i][j] = length of longest
    //(contiguous) suffix of A[0..i]
    // that is a subsequence of B[0..j]
    int[, ] dp = new int[1001, 1001];
 
    // r = maximum value over all
    // dp[i][j] computed so far
    int r = 0;
 
    for (int i = 0; i <= A.Length; ++i) {
      for (int j = 0; j <= B.Length; ++j) {
 
        dp[i, j] = 0;
 
        if (i > 0 && j > 0) {
 
          // any suffix of A[0..i]
          // which is a subsequence of B[0..j]
          // is also a subsequence of B[0..j-1]...
          dp[i, j] = dp[i, j - 1];
 
          // or, if last character matches (i.e.
          // A[i-1] == B[j-1]), and then the rest
          // of the suffix is a suffix of
          // A[0..i-1] and a subsequence of B[j-1]
          if (A[i - 1] == B[j - 1]) {
 
            dp[i, j] = Math.Max(
              dp[i, j], 1 + dp[i - 1, j - 1]);
            r = Math.Max(r, dp[i, j]);
          }
        }
      }
    }
 
    // r = the length of the
    // longest (contiguous) substring
    // of A that is a subsequence of B
    return A.Length - r;
  }
 
  // Driver code
  public static void Main()
  {
    string A = "edacb";
    string B = "abcde";
    Console.Write(minOperations(A, B));
  }
}
 
// This code is contributed by ukasp.

                    
<script>
       // JavaScript code for the above approach
 
 
       // Function to find min operations
       function minOperations(A, B) {
           // dp[i][j] = length of longest
           //(contiguous) suffix of A[0..i]
           // that is a subsequence of B[0..j]
           let dp = new Array(1001);
           for (let i = 0; i < dp.length; i++) {
               dp[i] = new Array(1001)
           }
 
           // r = maximum value over all
           // dp[i][j] computed so far
           let r = 0;
 
           for (let i = 0; i <= A.length; ++i) {
               for (let j = 0; j <= B.length; ++j) {
 
                   dp[i][j] = 0;
 
                   if (i && j) {
 
                       // any suffix of A[0..i]
                       // which is a subsequence of B[0..j]
                       // is also a subsequence of B[0..j-1]...
                       dp[i][j] = dp[i][j - 1];
 
                       // or, if last character matches (i.e.
                       // A[i-1] == B[j-1]), and then the rest
                       // of the suffix is a suffix of
                       // A[0..i-1] and a subsequence of B[j-1]
                       if (A[i - 1] == B[j - 1]) {
 
                           dp[i][j] = Math.max(
                               dp[i][j],
                               1 + dp[i - 1][j - 1]);
                           r = Math.max(r, dp[i][j]);
                       }
                   }
               }
           }
 
           // r = the length of the
           // longest (contiguous) substring
           // of A that is a subsequence of B
           return A.length - r;
       }
 
       // Driver code
 
       let A = "edacb";
       let B = "abcde";
       document.write(minOperations(A, B));
 
 
  // This code is contributed by Potta Lokesh
 
   </script>

                    

 
 


Output
3

Time Complexity : 
Auxiliary Space : 

Efficient Approach : using array instead of 2d matrix to optimize space complexity 

In previous code we can se that dp[i][j] is dependent upon dp[i-1][j-1] or dp[i][j-1] so we can assume that dp[i-1] is previous row and dp[i] is current row

Implementations Steps :

           a. If A[i] == B[j], then dp[j] = max(dp[j], prev + 1), where prev is the value of dp[j] before the update.
           b. Otherwise, dp[j] = 0.

Implementation :

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find min operations
int minOperations(string A, string B)
{
    // dp[j] = length of longest
    // (contiguous) suffix of A[0..i]
    // that is a subsequence of B[0..j]
    int dp[1001] = {0};
 
    // r = maximum value over all
    // dp[j] computed so far
    int r = 0;
 
    for (int i = 0; i < A.size(); ++i) {
        int prev = 0;
        for (int j = 0; j < B.size(); ++j) {
            int temp = dp[j];
            dp[j] = max(dp[j], (A[i] == B[j]) ? prev + 1 : 0);
            prev = temp;
            r = max(r, dp[j]);
        }
    }
 
    // r = the length of the
    // longest (contiguous) substring
    // of A that is a subsequence of B
    return A.size() - r;
}
 
// Driver code
int main()
{
    string A = "edacb";
    string B = "abcde";
    cout << minOperations(A, B);
    return 0;
}
 
//this code is contributed by bhardwajji

                    
// Java program for the above approach
public class Main {
    // Function to find min operations
    public static int minOperations(String A, String B) {
        // dp[j] = length of longest
        // (contiguous) suffix of A[0..i]
        // that is a subsequence of B[0..j]
        int[] dp = new int[1001];
 
        // r = maximum value over all
        // dp[j] computed so far
        int r = 0;
 
        for (int i = 0; i < A.length(); ++i) {
            int prev = 0;
            for (int j = 0; j < B.length(); ++j) {
                int temp = dp[j];
                dp[j] = Math.max(dp[j], (A.charAt(i) == B.charAt(j)) ? prev + 1 : 0);
                prev = temp;
                r = Math.max(r, dp[j]);
            }
        }
 
        // r = the length of the
        // longest (contiguous) substring
        // of A that is a subsequence of B
        return A.length() - r;
    }
 
    public static void main(String[] args) {
        String A = "edacb";
        String B = "abcde";
        System.out.println(minOperations(A, B));
    }
}

                    
# Python program for the above approach
 
# Function to find minimum operations
def minOperations(A, B):
 
    # dp[j] = length of longest
    # (contiguous) suffix of A[0..i]
    # that is a subsequence of B[0..j]
    dp = [0] * 1001
 
    # r = maximum value over all
    # dp[j] computed so far
    r = 0
 
    for i in range(len(A)):
        prev = 0
        for j in range(len(B)):
            temp = dp[j]
            dp[j] = max(dp[j], prev + 1 if A[i] == B[j] else 0)
            prev = temp
            r = max(r, dp[j])
 
    # r = the length of the longest (contiguous) substring
    # of A that is a subsequence of B
    return len(A) - r
 
# Driver code
A = "edacb"
B = "abcde"
print(minOperations(A, B))

                    
using System;
 
class MainClass
{
 
  // Function to find min operations
  public static int minOperations(string A, string B)
  {
 
    // dp[j] = length of longest
    // (contiguous) suffix of A[0..i]
    // that is a subsequence of B[0..j]
    int[] dp = new int[1001];
 
    // r = maximum value over all
    // dp[j] computed so far
    int r = 0;
 
    for (int i = 0; i < A.Length; ++i) {
      int prev = 0;
      for (int j = 0; j < B.Length; ++j) {
        int temp = dp[j];
        dp[j] = Math.Max(dp[j], (A[i] == B[j]) ? prev + 1 : 0);
        prev = temp;
        r = Math.Max(r, dp[j]);
      }
    }
 
    // r = the length of the
    // longest (contiguous) substring
    // of A that is a subsequence of B
    return A.Length - r;
  }
 
  public static void Main(string[] args) {
    string A = "edacb";
    string B = "abcde";
    Console.WriteLine(minOperations(A, B));
  }
}

                    
// JavaScript program for the above approach
 
// Function to find min operations
function minOperations(A, B) {
// dp[j] = length of longest
// (contiguous) suffix of A[0..i]
// that is a subsequence of B[0..j]
let dp = new Array(1001).fill(0);
 
// r = maximum value over all
// dp[j] computed so far
let r = 0;
 
for (let i = 0; i < A.length; ++i) {
let prev = 0;
for (let j = 0; j < B.length; ++j) {
let temp = dp[j];
dp[j] = Math.max(dp[j], A[i] == B[j] ? prev + 1 : 0);
prev = temp;
r = Math.max(r, dp[j]);
}
}
 
// r = the length of the
// longest (contiguous) substring
// of A that is a subsequence of B
return A.length - r;
}
 
// Driver code
let A = "edacb";
let B = "abcde";
console.log(minOperations(A, B));

                    

Output
3

Time Complexity : O(N^2)
Auxiliary Space : O(N)


Article Tags :