Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
Smallest string which not a subsequence of the given string
Next article icon

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

Last Updated : 07 Aug, 2023
Comments
Improve
Suggest changes
Like Article
Like
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: 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 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)



Next Article
Smallest string which not a subsequence of the given string
author
manoj_26
Improve
Article Tags :
  • Algorithms
  • Arrays
  • C++ Programs
  • Combinatorial
  • Competitive Programming
  • Data Structures
  • DSA
  • Dynamic Programming
  • Greedy
  • Hash
  • Pattern Searching
  • Randomized
  • School Programming
  • Strings
  • ASCII
  • Java-HashMap
  • subsequence
  • substring
Practice Tags :
  • Algorithms
  • Arrays
  • Combinatorial
  • Data Structures
  • Dynamic Programming
  • Greedy
  • Hash
  • Pattern Searching
  • Strings

Similar Reads

  • Minimum operations required to convert all characters of a String to a given Character
    Given string str, a character ch, and an integer K, the task is to find the minimum number of operations required to convert all the characters of string str to ch. Each operation involves converting K closest characters from each side of the index i, i.e., characters in the indices [i - K, i + K] c
    9 min read
  • Minimum number of alternate subsequences required to be removed to empty a Binary String
    Given a binary string S consisting of N characters, the task is to print the minimum number of operations required to remove all the characters from the given string S by removing a single character or removing any subsequence of alternate characters in each operation. Examples: Input: S = "010101"O
    6 min read
  • Minimum length of Run Length Encoding possible by removing at most K characters from a given string
    Given a string S of length N, consisting of lowercase English alphabets only, the task is to find the minimum possible length of run-length-encoding that can be generated by removing at most K characters from the string S. Examples: Input: S = "abbbcdcdd", N = 9, K = 2 Output: 5 Explanation: One pos
    10 min read
  • Smallest string which not a subsequence of the given string
    Given a string str, consisting of lowercase alphabets, the task is to find the shortest string which is not a subsequence of the given string. If multiple strings exist, then print any one of them. Examples: Input: str = "abaabcc" Output: d Explanation: One of the possible shortest string which is n
    6 min read
  • Minimize cost to rearrange substrings to convert a string to a Balanced Bracket Sequence
    Given a string S of length N consisting of characters "(" and ")" only, the task is to convert the given string into a balanced parenthesis sequence by selecting any substring from the given string S and reorder the characters of that substring. Considering length of each substring to be the cost of
    7 min read
  • Lexicographically smallest permutation of a string that contains all substrings of another string
    Given two strings A and B, the task is to find lexicographically the smallest permutation of string B such that it contains every substring from the string A as its substring. Print “-1” if no such valid arrangement is possible.Examples: Input: A = "aa", B = "ababab" Output: aaabbb Explanation: All
    10 min read
  • C++ Program to Minimize characters to be changed to make the left and right rotation of a string same
    Given a string S of lowercase English alphabets, the task is to find the minimum number of characters to be changed such that the left and right rotation of the string are the same. Examples: Input: S = “abcd”Output: 2Explanation:String after the left shift: “bcda”String after the right shift: “dabc
    3 min read
  • C++ Program to Replace a Character in a String
    Given a string S, c1 and c2. Replace character c1 with c2 and c2 with c1. Examples: Input: grrksfoegrrks, c1 = e, c2 = r Output: geeksforgeeks Input: ratul, c1 = t, c2 = h Output: rahul Traverse through the string and check for the occurrences of c1 and c2. If c1 is found then replace it with c2 and
    3 min read
  • C++ Program for Minimum move to end operations to make all strings equal
    Given n strings that are permutations of each other. We need to make all strings same with an operation that takes front character of any string and moves it to the end.Examples: Input : n = 2 arr[] = {"molzv", "lzvmo"} Output : 2 Explanation: In first string, we remove first element("m") from first
    3 min read
  • Reduce the string to minimum length with the given operation
    Given a string str consisting of lowercase and uppercase characters, the task is to find the minimum possible length the string can be reduced to after performing the given operation any number of times. In a single operation, any two consecutive characters can be removed if they represent the same
    6 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences