Convert given string to another by minimum replacements of subsequences by its smallest character
Given two strings A and B, the task is to count the minimum number of operations required to convert the string A to B. In one operation, select a subsequence from string A and convert every character of that subsequence to the smallest character present in it. If it is not possible to transform, then print “-1”.
Examples:
Input: A = “abcab”, B = “aabab”
Output: 2
Explanation:
Operation 1: Replacing characters from indices {2, 1} by the smallest character from those indices(i.e. ‘b’), transforms A to “abbab”.
Operation 2: Replacing characters from indices {1, 0}, by the smallest character from those indices(i.e. ‘a’), transforms A to “aabab”.
Therefore, the count of operations required to convert string A to B is 2.Input: A = “aaa”, B = “aab”
Output: -1
Explanation:
There is no possible way to convert A to B as string A doesn’t contain ‘b’.
Approach: The approach is based on the idea that if any character at index i of string A is less than the character at index i of string B, then it is impossible to change A to B because changing a character to a character smaller than itself is not allowed. Below are the steps:
- Initialize two array of vectors convChar and str1array, of size 26. Each index of these arrays corresponds to a character.
- The ith index of convChar contains indices of string A that should be converted to the ith alphabet and str1array contains the indices of all characters of string A.
- Initialize a Hashmap convertMap that indicates the particular character to which the character at index i of string A should be converted to.
- Iterate over both strings simultaneously, three possible cases can occur:
- If ith character of string A is less than ith character of string B, then it is impossible to change A to B. Therefore, print “-1”.
- If both characters on the current index are same then it requires no change.
- Otherwise, insert this index i in convChar array on the index corresponding to the ith character of string B and insert the character value of ith character in string B in the Hashmap convertMap with the key value as i.
- Initialize the a variable ret that counts the minimum operations required and a vector retV to store the set of operations.
- Now iterate over all the alphabets in reverse order. Do the following steps in each iteration:
- Check for each alphabet, if there is at least one index that should be converted to the current alphabet.
- Increase ret by one to count the required number of steps. Let v be the vector of indices that should be converted to the current alphabet with index i and v1 be the vector that contains all the indices of string A. Then two cases can occur:
- If v1 has no element, then current alphabet is not present in string A. Therefore, it is not possible to change A to B.
- Otherwise, proceed to next step.
- Iterate for each index j of vector v1. In this iteration, search for the minimum index to include in the set S.
- If jth alphabet of vector v1 is present in convertMap, it means that this alphabet has been converted or will convert to another character in an operation. If it has been converted in one of previous operations, then proceed to next iteration of v1.
- Else add this index in the set. And come out of the loop
- If any such index j is not found in vector v1, then it is impossible to convert string A to B. Hence print “-1”
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to return the minimum number // of operation void transformString(string str1, string str2) { // Storing data int N = str1.length(); vector< int > convChar[26]; vector< int > str1array[26]; // Initialize both arrays for ( int i = 0; i < 26; i++) { vector< int > v; convChar[i] = v; str1array[i] = v; } // Stores the index of character map< int , char > convertMap; // Filling str1array, convChar // and hashmap convertMap. for ( int i = 0; i < N; i++) { str1array[str1[i] - 'a' ].push_back(i); } for ( int i = 0; i < N; i++) { // Not possible to convert if (str1[i] < str2[i]) { cout << -1 << endl; return ; } else if (str1[i] == str2[i]) continue ; else { convChar[str2[i] - 'a' ].push_back(i); convertMap[i] = str2[i]; } } // Calculate result // Initializing return values int ret = 0; vector<vector< int > > retv; // Iterating the character from // the end for ( int i = 25; i >= 0; i--) { vector< int > v = convChar[i]; if (v.size() == 0) continue ; // Increment the number of // operations ret++; vector< int > v1 = str1array[i]; // Not possible to convert if (v1.size() == 0) { cout << -1 << endl; return ; } // to check whether the final // element has been added // in set S or not. bool isScompleted = false ; for ( int j = 0; j < v1.size(); j++) { // Check if v1[j] is present // in hashmap or not if (convertMap.find(v1[j]) != convertMap.end()) { char a = convertMap[v1[j]]; // Already converted then // then continue if (a > i + 'a' ) continue ; else { v.push_back(v1[j]); isScompleted = true ; retv.push_back(v); break ; } } else { v.push_back(v1[j]); isScompleted = true ; retv.push_back(v); break ; } } // Not possible to convert if (!isScompleted) { cout << -1 << endl; return ; } } // Print the result cout << ret << endl; } // Driver Code int main() { // Given strings string A = "abcab" ; string B = "aabab" ; // Function Call transformString(A, B); return 0; } |
Java
// Java program for the above approach import java.util.*; import java.lang.*; class GFG{ // Function to return the minimum number // of operation static void transformString(String str1, String str2) { // Storing data int N = str1.length(); ArrayList< ArrayList<Integer>> convChar = new ArrayList<>(); ArrayList< ArrayList<Integer>> str1array = new ArrayList<>(); // Initialize both arrays for ( int i = 0 ; i < 26 ; i++) { convChar.add( new ArrayList<>()); str1array.add( new ArrayList<>()); } // Stores the index of character Map<Integer, Character> convertMap = new HashMap<>(); // Filling str1array, convChar // and hashmap convertMap. for ( int i = 0 ; i < N; i++) { str1array.get(str1.charAt(i) - 'a' ).add(i); } for ( int i = 0 ; i < N; i++) { // Not possible to convert if (str1.charAt(i) < str2.charAt(i)) { System.out.println(- 1 ); return ; } else if (str1.charAt(i) == str2.charAt(i)) continue ; else { convChar.get(str2.charAt(i) - 'a' ).add(i); convertMap.put(i,str2.charAt(i)); } } // Calculate result // Initializing return values int ret = 0 ; ArrayList< ArrayList<Integer>> retv = new ArrayList<>(); // Iterating the character from // the end for ( int i = 25 ; i >= 0 ; i--) { ArrayList<Integer> v = convChar.get(i); if (v.size() == 0 ) continue ; // Increment the number of // operations ret++; ArrayList<Integer> v1 = str1array.get(i); // Not possible to convert if (v1.size() == 0 ) { System.out.println(- 1 ); return ; } // To check whether the final // element has been added // in set S or not. boolean isScompleted = false ; for ( int j = 0 ; j < v1.size(); j++) { // Check if v1[j] is present // in hashmap or not if (convertMap.containsKey(v1.get(j))) { char a = convertMap.get(v1.get(j)); // Already converted then // then continue if (a > i + 'a' ) continue ; else { v.add(v1.get(j)); isScompleted = true ; retv.add(v); break ; } } else { v.add(v1.get(j)); isScompleted = true ; retv.add(v); break ; } } // Not possible to convert if (!isScompleted) { System.out.println(- 1 ); return ; } } // Print the result System.out.println(ret); } // Driver Code public static void main (String[] args) { // Given strings String A = "abcab" ; String B = "aabab" ; // Function call transformString(A, B); } } // This code is contributed by offbeat |
Python3
# Python3 program for the above approach # Function to return the minimum number # of operation def transformString(str1, str2): # Storing data N = len (str1) convChar = [] str1array = [] # Initialize both arrays for i in range ( 26 ): convChar.append([]) str1array.append([]) # Stores the index of character convertMap = {} # Filling str1array, convChar # and hashmap convertMap. for i in range (N): str1array[ ord (str1[i]) - ord ( 'a' )].append(i) for i in range (N): # Not possible to convert if (str1[i] < str2[i]): print ( - 1 ) return elif (str1[i] = = str2[i]): continue else : convChar[ ord (str2[i]) - ord ( 'a' )].append(i) convertMap[i] = str2[i] # Calculate result # Initializing return values ret = 0 retv = [] # Iterating the character from # the end for i in range ( 25 , - 1 , - 1 ): v = convChar[i] if ( len (v) = = 0 ): continue # Increment the number of # operations ret + = 1 ; v1 = str1array[i] # Not possible to convert if ( len (v1) = = 0 ): print ( - 1 ) return # To check whether the final # element has been added # in set S or not. isScompleted = False for j in range ( len (v1)): # Check if v1[j] is present # in hashmap or not if (v1[j] in convertMap): a = v1[j] # Already converted then # then continue if (a > i + ord ( 'a' )): continue else : v.append(v1[j]) isScompleted = True retv.append(v) break else : v.append(v1[j]) isScompleted = True retv.append(v) break # Not possible to convert if (isScompleted = = False ): print ( - 1 ) return # Print the result print (ret) # Driver Code A = "abcab" B = "aabab" # Function call transformString(A, B) # This code is contributed by dadi madhav |
C#
// C# program for the above approach using System; using System.Collections.Generic; class GFG{ // Function to return the minimum number // of operation static void transformString( string str1, string str2) { // Storing data int N = str1.Length; List<List< int >> convChar = new List<List< int >>(); List<List< int >> str1array = new List<List< int >>(); // Initialize both arrays for ( int i = 0; i < 26; i++) { convChar.Add( new List< int >()); str1array.Add( new List< int >()); } // Stores the index of character Dictionary< int , char > convertMap = new Dictionary< int , char >(); // Filling str1array, convChar // and hashmap convertMap. for ( int i = 0; i < N; i++) { str1array[str1[i] - 'a' ].Add(i); } for ( int i = 0; i < N; i++) { // Not possible to convert if (str1[i] < str2[i]) { Console.WriteLine(-1); return ; } else if (str1[i] == str2[i]) continue ; else { convChar[str2[i] - 'a' ].Add(i); convertMap[i] = str2[i]; } } // Calculate result // Initializing return values int ret = 0; List<List< int >> retv = new List<List< int >>(); // Iterating the character from // the end for ( int i = 25; i >= 0; i--) { List< int > v = convChar[i]; if (v.Count == 0) continue ; // Increment the number of // operations ret++; List< int > v1 = str1array[i]; // Not possible to convert if (v1.Count == 0) { Console.WriteLine(-1); return ; } // To check whether the final // element has been added // in set S or not. bool isScompleted = false ; for ( int j = 0; j < v1.Count; j++) { // Check if v1[j] is present // in hashmap or not if (convertMap.ContainsKey(v1[j])) { char a = convertMap[v1[j]]; // Already converted then // then continue if (a > i + 'a' ) continue ; else { v.Add(v1[j]); isScompleted = true ; retv.Add(v); break ; } } else { v.Add(v1[j]); isScompleted = true ; retv.Add(v); break ; } } // Not possible to convert if (!isScompleted) { Console.WriteLine(-1); return ; } } // Print the result Console.WriteLine(ret); } // Driver code static void Main() { // Given strings string A = "abcab" ; string B = "aabab" ; // Function call transformString(A, B); } } // This code is contributed by divyesh072019 |
Javascript
<script> // JavaScript program for the above approach // Function to return the minimum number // of operation function transformString(str1, str2) { // Storing data let N = str1.length let convChar = [] let str1array = [] // Initialize both arrays for (let i = 0; i < 26; i++) { convChar.push([]) str1array.push([]) } // Stores the index of character let convertMap = new Map() // Filling str1array, convChar // and hashmap convertMap. for (let i = 0; i < N; i++) { str1array[str1.charCodeAt(i) - 'a' .charCodeAt(0)].push(i) } for (let i = 0; i < N; i++) { // Not possible to convert if (str1.charCodeAt(i) < str2.charCodeAt(i)) { document.write(-1) return } else if (str1[i] == str2[i]) continue else convChar[str2.charCodeAt(i) - 'a' .charCodeAt(0)].push(i) convertMap[i] = str2[i] } // Calculate result // Initializing return values let ret = 0 let retv = [] // Iterating the character from // the end for (let i = 25; i >= 0; i--) { let v = convChar[i] if (v.length == 0) continue // Increment the number of // operations ret += 1; v1 = str1array[i] // Not possible to convert if (v1.length == 0){ document.write(-1) return } // To check whether the final // element has been added // in set S or not. isScompleted = false for (let j = 0; j < v1.length; j++) { // Check if v1[j] is present // in hashmap or not if (convertMap.has(v1[j])){ let a = v1[j] // Already converted then // then continue if (a > i + 'a' .charCodeAt(0)) continue else { v.push(v1[j]) isScompleted = true retv.append(v) break } } else { v.push(v1[j]) isScompleted = true retv.push(v) break } } // Not possible to convert if (isScompleted == false ){ document.write(-1) return } } // Print the result document.write(ret) } // Driver Code let A = "abcab" let B = "aabab" // Function call transformString(A, B) // This code is contributed by shinjanpatra </script> |
2
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...