Skip to content
Related Articles

Related Articles

Minimum subsequences of a string A required to be appended to obtain the string B
  • Last Updated : 05 Feb, 2021

Given two strings A and B, the task is to count the minimum number of operations required to construct the string B by following operations: 
 

  • Select a subsequence of the string A.
  • Append the subsequence at the newly formed string (initially empty).

Print the minimum count of operations required. If it is impossible to make the new string equal to B by applying the given operations, then print -1.

Examples:

Input: A = “abc”, B = “abac”
Output: 2
Explanation:
Initially, C = “”. 
Step 1: Select subsequence “ab” from string A and append it to the empty string C, i.e. C = “ab”.
Step 2: Select subsequence “ac” from string A and append it to the end of string C, i.e. C = “abac”. 
Now, the string C is same as string B.
Therefore, count of operations required is 2.

Input: A = “geeksforgeeks”, B = “programming”
Output: -1

Approach: Follow the below steps to solve this problem:



  1. Initialize a Map to map characters present in the string A with their respective indices.
  2. For each character in string A, keep track of all of its occurrences.
  3. Initialize a variable, say ans, to store the count of operations required. As the number of operations must be greater than 1, set ans = 1.
  4. Iterate over the characters of string B and check if the character is present in the string A or not by using the Map.
  5. Lastly, maximize the length of the subsequence chosen from the string A for each operation.
  6. Finally, print the minimum operations required.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to count the minimum
// subsequences of a string A required
// to be appended to obtain the string B
void countminOpsToConstructAString(string A,
                                   string B)
{
    // Size of the string
    int N = A.length();
 
    int i = 0;
 
    // Maps characters to their
    // respective indices
    map<char, set<int> > mp;
 
    // Insert indices of characters
    // into the sets
    for (i = 0; i < N; i++) {
        mp[A[i]].insert(i);
    }
 
    // Stores the position of the last
    // visited index in the string A.
    // Initially set it to -1.
    int previous = -1;
 
    // Stores the required count
    int ans = 1;
 
    // Iterate over the characters of B
    for (i = 0; i < B.length(); i++) {
        char ch = B[i];
 
        // If the character in B is
        // not present in A, return -1
        if (mp[ch].size() == 0) {
            cout << -1;
            return;
        }
 
        // Fetch the next index from B[i]'s set
        auto it = mp[ch].upper_bound(previous);
 
        // If the iterator points to
        // the end of that set
        if (it == mp[ch].end()) {
 
            previous = -1;
            ans++;
            --i;
            continue;
        }
 
        // If it doesn't point to the
        // end, update  previous
        previous = *it;
    }
 
    // Print the answer
    cout << ans;
}
 
// Driver Code
int main()
{
    string A = "abc", B = "abac";
    countminOpsToConstructAString(A, B);
 
    return 0;
}

Python3




# Python3 program for the above approac
from bisect import bisect_right
 
# Function to count the minimum
# subsequences of a A required
# to be appended to obtain the B
def countminOpsToConstructAString(A, B):
   
    # Size of the string
    N = len(A)
    i = 0
 
    # Maps characters to their
    # respective indices
    mp = [[] for i in range(26)]
 
    # Insert indices of characters
    # into the sets
    for i in range(N):
        mp[ord(A[i]) - ord('a')].append(i)
 
    # Stores the position of the last
    # visited index in the A.
    # Initially set it to -1.
    previous = -1
 
    # Stores the required count
    ans, i = 1, 0
 
    # Iterate over the characters of B
    while i < len(B):
        ch = B[i]
 
        # If the character in B is
        # not present in A, return -1
        if (len(mp[ord(ch) - ord('a')]) == 0):
            print(-1)
            return
 
        # Fetch the next index from B[i]'s set
        it = bisect_right(mp[ord(ch) - ord('a')], previous)
 
        # If the iterator points to
        # the end of that set
        if (it == len(mp[ord(ch) - ord('a')])):
            previous = -1
            ans += 1
            # i -= 1
            continue
 
        # If it doesn't poto the
        # end, update  previous
        previous = mp[ord(ch) - ord('a')][it]
        i += 1
 
    # Prthe answer
    print (ans)
 
# Driver Code
if __name__ == '__main__':
    A, B = "abc", "abac"
    countminOpsToConstructAString(A, B)
 
    # This code is contributed by mohit kumar 29.
Output: 
2

 

Time Complexity: O(N * logN)
Auxiliary Space: O(N) 

My Personal Notes arrow_drop_up
Recommended Articles
Page :