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:
- Initialize a Map to map characters present in the string A with their respective indices.
- For each character in string A, keep track of all of its occurrences.
- 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.
- Iterate over the characters of string B and check if the character is present in the string A or not by using the Map.
- Lastly, maximize the length of the subsequence chosen from the string A for each operation.
- 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; } |
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<Character, TreeSet<Integer> > 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<Integer>()); } 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); |
2
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Please Login to comment...