Open In App

Convert given string to another by minimum replacements of subsequences by its smallest character

Improve
Improve
Like Article
Like
Save
Share
Report

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:
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 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>


Output

2

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



Last Updated : 07 Aug, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads