Open In App

# Minimum subsequences of a string A required to be appended to obtain the string B

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 ``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;``}`

## Java

 `// Java program for the above approach` `import` `java.util.*;` `class` `GFG {``    ``// Function to count the minimum``    ``// subsequences of a string A required``    ``// to be appended to obtain the string B``    ``static` `void` `countminOpsToConstructAString(String A,``                                              ``String B)``    ``{``        ``// Size of the string``        ``int` `N = A.length();` `        ``int` `i = ``0``;` `        ``// Maps characters to their``        ``// respective indices``        ``Map > mp``            ``= ``new` `HashMap<>();` `        ``// Insert indices of characters``        ``// into the sets``        ``for` `(i = ``0``; i < N; i++) {``            ``if` `(!mp.containsKey(A.charAt(i))) {``                ``mp.put(A.charAt(i), ``new` `TreeSet());``            ``}``            ``mp.get(A.charAt(i)).add(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.charAt(i);` `            ``// If the character in B is``            ``// not present in A, return -1``            ``if` `(!mp.containsKey(ch)``                ``|| mp.get(ch).size() == ``0``) {``                ``System.out.print(``"-1"``);``                ``return``;``            ``}` `            ``// Fetch the next index from B[i]'s set``            ``Integer it = mp.get(ch).higher(previous);` `            ``// If the iterator points to``            ``// the end of that set``            ``if` `(it == ``null``) {` `                ``previous = -``1``;``                ``ans++;``                ``i--;``                ``continue``;``            ``}` `            ``// If it doesn't point to the``            ``// end, update previous``            ``previous = it;``        ``}` `        ``// Print the answer``        ``System.out.print(ans);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``String A = ``"abc"``, B = ``"abac"``;``        ``countminOpsToConstructAString(A, B);``    ``}``}` `// Contributed by adityashae15`

## Python3

 `# Python3 program for the above approach``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 point to the``        ``# end, update  previous``        ``previous ``=` `mp[``ord``(ch) ``-` `ord``(``'a'``)][it]``        ``i ``+``=` `1` `    ``# Print answer``    ``print` `(ans)` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``A, B ``=` `"abc"``, ``"abac"``    ``countminOpsToConstructAString(A, B)` `    ``# This code is contributed by mohit kumar 29.`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `class` `GFG``{``  ` `    ``// Function to count the minimum``    ``// subsequences of a string A required``    ``// to be appended to obtain the string B``    ``static` `void` `CountminOpsToConstructAString(``string` `A,``                                              ``string` `B)``    ``{``        ``// Size of the string``        ``int` `N = A.Length;` `        ``int` `i = 0;` `        ``// Maps characters to their``        ``// respective indices``        ``Dictionary<``char``, SortedSet<``int``> > mp``            ``= ``new` `Dictionary<``char``, SortedSet<``int``> >();` `        ``// Insert indices of characters``        ``// into the sets``        ``for` `(i = 0; i < N; i++) {``            ``if` `(!mp.ContainsKey(A[i])) {``                ``mp.Add(A[i], ``new` `SortedSet<``int``>());``            ``}``            ``mp[A[i]].Add(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.ContainsKey(ch) || mp[ch].Count == 0) {``                ``Console.Write(``"-1"``);``                ``return``;``            ``}` `            ``// Fetch the next index from B[i]'s set``            ``var` `view``                ``= mp[ch].GetViewBetween(previous + 1, N);``            ``if` `(view.Count == 0) {``                ``previous = -1;``                ``ans++;``                ``i--;``                ``continue``;``            ``}``            ``int` `it = view.Min;` `            ``// If it doesn't point to the``            ``// end, update previous``            ``previous = it;``        ``}` `        ``// Print the answer``        ``Console.Write(ans);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main()``    ``{``        ``string` `A = ``"abc"``, B = ``"abac"``;``        ``CountminOpsToConstructAString(A, B);``    ``}``}` `// This code is contributed by phasing17`

## Javascript

 `// JavaScript program for the above approach``function` `countminOpsToConstructAString(A, B) {``  ` `    ``// Size of the string``    ``const N = A.length;``    ``let i = 0;` `    ``// Maps characters to their``    ``// respective indices``    ``const mp = ``new` `Array(26).fill(``null``).map(() => []);` `    ``// Insert indices of characters``    ``// into the sets``    ``for` `(i = 0; i < N; i++) {``        ``mp[A.charCodeAt(i) - ``'a'``.charCodeAt(0)].push(i);``    ``}` `    ``// Stores the position of the last``    ``// visited index in the A.``    ``// Initially set it to -1.``    ``let previous = -1;` `    ``// Stores the required count``    ``let ans = 1;``    ``i = 0;` `    ``// Iterate over the characters of B``    ``while` `(i < B.length) {``        ``const ch = B[i];` `        ``// If the character in B is``        ``// not present in A, return -1``        ``if` `(mp[ch.charCodeAt(0) - ``'a'``.charCodeAt(0)].length == 0) {``            ``console.log(-1);``            ``return``;``        ``}` `        ``// Fetch the next index from B[i]'s set``        ``const it = mp[ch.charCodeAt(0) - 'a``'.charCodeAt(0)].findIndex(idx => idx > previous);` `        ``// If the iterator points to``        ``// the end of that set``        ``if (it == mp[ch.charCodeAt(0) - '``a``'.charCodeAt(0)].length) {``            ``previous = -1;``            ``ans += 1;``            ``// i -= 1``            ``continue;``        ``}` `        ``// If it doesn'``t point to the``        ``// end, update previous``        ``previous = mp[ch.charCodeAt(0) - ``'a'``.charCodeAt(0)][it];``        ``i += 1;``    ``}` `    ``// Print answer``    ``console.log(ans);``}` `// Driver Code``const A = ``"abc"``, B = ``"abac"``;``countminOpsToConstructAString(A, B);`

Output:

`2`

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