Open In App

Minimize count of given operations required to make two given strings permutations of each other

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given two strings str1 and str2, the task is to count the minimum number of operations of the following three types on one of the two strings that are required to make str1 and str2 permutations of each other:

  1. Insert a character into the string.
  2. Remove a character from the string.
  3. Replace a character with another character from the string.

Note: All the above operations are of equal cost.

Examples:

Input: str1 = “geeksforgeeks”, str2 = “geeksforcoder”
Output: 4
Explanation: Rearrange the string str2 to “geeksforcedor”
Replace the value of str1[8] to ‘c’.
Replace the value of str1[10] to ‘d’.
Replace the value of str1[11] to ‘o’.
Replace the value of str1[12] to ‘r’.
Therefore, the required output is 4.

Input: str1 = “geeks”, str2 = “keeg”
Output: 1

 

Approach: The problem can be solved using Hashing to store the frequency of each character of both the string. Below are the observations to solve the problem:

X = Number of characters which are present in both string, str1 and str2.
N1 – X = Number of characters present only in str1.
N2 – X = Number of characters present only in str2.
Total number of replacement operations = min(N1 – X, N2 – X)
Total number of insert/Remove operations = max(N1 – X, N2 – X) – min(N1 – X, N2 – X).
Therefore, total number of operations = max(N1 – X, N2 – X),

Follow the steps below to solve the problem:

  1. Initialize two arrays, say freq1[] and freq2[] to store the frequency of all the characters of str1 and str2 respectively.
  2. Traverse both the strings and store the frequency of each character of both the strings in arrays freq1[] and freq2[] respectively.
  3. Traverse both the arrays freq1[] and freq2[].
  4. For every ith character, if freq1[i] exceeds freq2[i], then replace freq1[i] to freq1[i] – freq2[i] and set freq2[i] = 0 and vice-versa.
  5. Finally, calculate the sum of the arrays freq1[] and freq2[], and print the maximum between them as the answer

Below is the implement the above approach:
 

C++




// C++ program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to minimize the count of
// operations to make str1 and str2
// permutations of each other
int ctMinEdits(string str1, string str2)
{
    int N1 = str1.length();
    int N2 = str2.length();
 
    // Store the frequency of
    // each character of str1
    int freq1[256] = { 0 };
    for (int i = 0; i < N1; i++) {
        freq1[str1[i]]++;
    }
 
    // Store the frequency of
    // each character of str2
    int freq2[256] = { 0 };
    for (int i = 0; i < N2; i++) {
        freq2[str2[i]]++;
    }
 
    // Traverse the freq1[] and freq2[]
    for (int i = 0; i < 256; i++) {
 
        // If frequency of character in
        // str1 is greater than str2
        if (freq1[i] > freq2[i]) {
            freq1[i] = freq1[i]
                       - freq2[i];
            freq2[i] = 0;
        }
 
        // Otherwise
        else {
            freq2[i] = freq2[i]
                       - freq1[i];
            freq1[i] = 0;
        }
    }
 
    // Store sum of freq1[]
    int sum1 = 0;
 
    // Store sum of freq2[]
    int sum2 = 0;
 
    for (int i = 0; i < 256; i++) {
        sum1 += freq1[i];
        sum2 += freq2[i];
    }
 
    return max(sum1, sum2);
}
 
// Driver Code
int main()
{
    string str1 = "geeksforgeeks";
    string str2 = "geeksforcoder";
    cout << ctMinEdits(str1, str2);
}


Java




// Java program to implement
// the above approach
import java.util.*;
import java.io.*;
import java.lang.Math;
 
class GFG{
     
// Function to minimize the count of
// operations to make str1 and str2
// permutations of each other
static int ctMinEdits(String str1, String str2)
{
    int N1 = str1.length();
    int N2 = str2.length();
   
    // Store the frequency of
    // each character of str1
    int freq1[] = new int[256];
    Arrays.fill(freq1, 0);
     
    for(int i = 0; i < N1; i++)
    {
        freq1[str1.charAt(i)]++;
    }
   
    // Store the frequency of
    // each character of str2
    int freq2[] = new int[256];
    Arrays.fill(freq2, 0);
     
    for(int i = 0; i < N2; i++)
    {
        freq2[str2.charAt(i)]++;
    }
   
    // Traverse the freq1[] and freq2[]
    for(int i = 0; i < 256; i++)
    {
         
        // If frequency of character in
        // str1 is greater than str2
        if (freq1[i] > freq2[i])
        {
            freq1[i] = freq1[i] - freq2[i];
            freq2[i] = 0;
        }
   
        // Otherwise
        else
        {
            freq2[i] = freq2[i] - freq1[i];
            freq1[i] = 0;
        }
    }
   
    // Store sum of freq1[]
    int sum1 = 0;
   
    // Store sum of freq2[]
    int sum2 = 0;
   
    for(int i = 0; i < 256; i++)
    {
        sum1 += freq1[i];
        sum2 += freq2[i];
    }
   
    return Math.max(sum1, sum2);
}
 
// Driver Code
public static void main(final String[] args)
{
    String str1 = "geeksforgeeks";
    String str2 = "geeksforcoder";
     
    System.out.println(ctMinEdits(str1, str2));
}
}
 
// This code is contributed by bikram2001jha


Python3




# Python3 program to implement
# the above approach
  
# Function to minimize the count of
# operations to make str1 and str2
# permutations of each other
def ctMinEdits(str1, str2):
     
    N1 = len(str1)
    N2 = len(str2)
  
    # Store the frequency of
    # each character of str1
    freq1 =  [0] * 256
    for i in range(N1):
        freq1[ord(str1[i])] += 1
     
    # Store the frequency of
    # each character of str2
    freq2 = [0] * 256
    for i in range(N2):
        freq2[ord(str2[i])] += 1
     
    # Traverse the freq1[] and freq2[]
    for i in range(256):
  
        # If frequency of character in
        # str1 is greater than str2
        if (freq1[i] > freq2[i]):
            freq1[i] = freq1[i] - freq2[i]
            freq2[i] = 0
  
        # Otherwise
        else:
            freq2[i] = freq2[i] - freq1[i]
            freq1[i] = 0
         
    # Store sum of freq1[]
    sum1 = 0
  
    # Store sum of freq2[]
    sum2 = 0
  
    for i in range(256):
        sum1 += freq1[i]
        sum2 += freq2[i]
     
    return max(sum1, sum2)
 
# Driver Code
str1 = "geeksforgeeks"
str2 = "geeksforcoder"
 
print(ctMinEdits(str1, str2))
 
# This code is contributed by code_hunt


C#




// C# program to implement
// the above approach
using System;
 
class GFG{
      
// Function to minimize the count of
// operations to make str1 and str2
// permutations of each other
static int ctMinEdits(string str1, string str2)
{
    int N1 = str1.Length;
    int N2 = str2.Length;
    
    // Store the frequency of
    // each character of str1
    int[] freq1 = new int[256];
    freq1[0] = str1[0];
      
    for(int i = 0; i < N1; i++)
    {
        freq1[str1[i]]++;
    }
    
    // Store the frequency of
    // each character of str2
    int[] freq2 = new int[256];
    freq2[0] = str2[0];
      
    for(int i = 0; i < N2; i++)
    {
        freq2[str2[i]]++;
    }
    
    // Traverse the freq1[] and freq2[]
    for(int i = 0; i < 256; i++)
    {
         
        // If frequency of character in
        // str1 is greater than str2
        if (freq1[i] > freq2[i])
        {
            freq1[i] = freq1[i] - freq2[i];
            freq2[i] = 0;
        }
    
        // Otherwise
        else
        {
            freq2[i] = freq2[i] - freq1[i];
            freq1[i] = 0;
        }
    }
    
    // Store sum of freq1[]
    int sum1 = 0;
    
    // Store sum of freq2[]
    int sum2 = 0;
    
    for(int i = 0; i < 256; i++)
    {
        sum1 += freq1[i];
        sum2 += freq2[i];
    }
    return Math.Max(sum1, sum2);
}
  
// Driver Code
public static void Main()
{
    string str1 = "geeksforgeeks";
    string str2 = "geeksforcoder";
      
    Console.WriteLine(ctMinEdits(str1, str2));
}
}
 
// This code is contributed by code_hunt


Javascript




<script>
 
// Javascript program to implement
// the above approach
 
// Function to minimize the count of
// operations to make str1 and str2
// permutations of each other
function ctMinEdits(str1, str2)
{
    let N1 = str1.length;
    let N2 = str2.length;
    
    // Store the frequency of
    // each character of str1
    let freq1 = new Array(256).fill(0);
      
    for(let i = 0; i < N1; i++)
    {
        freq1[str1[i].charCodeAt()]++;
    }
    
    // Store the frequency of
    // each character of str2
    let freq2 = new Array(256).fill(0);
      
    for(let i = 0; i < N2; i++)
    {
        freq2[str2[i].charCodeAt()]++;
    }
    
    // Traverse the freq1[] and freq2[]
    for(let i = 0; i < 256; i++)
    {
          
        // If frequency of character in
        // str1 is greater than str2
        if (freq1[i] > freq2[i])
        {
            freq1[i] = freq1[i] - freq2[i];
            freq2[i] = 0;
        }
    
        // Otherwise
        else
        {
            freq2[i] = freq2[i] - freq1[i];
            freq1[i] = 0;
        }
    }
    
    // Store sum of freq1[]
    let sum1 = 0;
    
    // Store sum of freq2[]
    let sum2 = 0;
    
    for(let i = 0; i < 256; i++)
    {
        sum1 += freq1[i];
        sum2 += freq2[i];
    }
    
    return Math.max(sum1, sum2);
}
 
// Driver Code
 
    let str1 = "geeksforgeeks";
    let str2 = "geeksforcoder";
      
    document.write(ctMinEdits(str1.split(''), str2.split('')));
      
</script>


Output

4





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

Another method using Hashing: Unordered_map(): 

It made the code simpler and also reduce space requirement.

1. Create an unordered map mp to store the frequency of each character in both strings.
2. Loop over the str1 and update character  frequency in the map.
3. Loop over the str2 and update characters frequency in the map.
4. Calculate the absolute difference in frequency for each character in the map.
5. Now store the sum of frequency differences in the two variables f1 and f2 for each strings.
6. Now, return the maximum of f1 and f2.

C++




// C++ code for above approach
#include <bits/stdc++.h>
using namespace std;
 
// function to find the minimum no. of edits required.
int CntMinEdit(string str1, string str2)
{
    // counter variable
    int ans = 0;
     
    // unordered map to store the frequency of each character in both strings
    unordered_map<char,pair<int,int>>mp;
     
    // loop to store frequency of str1 in the map
    for(int i = 0; i<str1.length();i++)
        mp[str1[i]].first++;
    
   // loop to store frequency of str2 in the map
    for(int i = 0; i<str2.length();i++)
        mp[str2[i]].second++;
     
   // Variables to store the sum of frequency difference of each strings
        int f1 = 0, f2 = 0;
    // loop to calculate the difference in frequency for each character
    for(auto it:mp)
    {
        if(it.second.first>it.second.second)
        f1+=it.second.first-it.second.second;
        else
        f2 += it.second.second-it.second.first;
    }
  // return max of f1 and f2
    return max(f2,f1);
}
 
// Driver code
int main()
{
    // Two strings taken
    string str1 = "geeksforgeeks";
    string str2 = "geeksforcoder";
     
    // printing the output
    cout << CntMinEdit(str1, str2)<<endl;
   
    //Example 2
    str1 = "geeks";
    str2 = "keeg";
   cout << CntMinEdit(str1, str2)<<endl;
}


Java




// Java implementation of above approach
import java.util.*;
 
public class Main {
     
    // function to find the minimum no. of edits required.
    public static int cntMinEdit(String str1, String str2) {
    
        int ans = 0;
         
        // HashMap to store the frequency
        HashMap<Character, int[]> mp = new HashMap<>();
         
        // loop to store frequency of str1 in the map
        for(int i = 0; i<str1.length(); i++) {
            char c = str1.charAt(i);
            if(mp.containsKey(c)) {
                mp.get(c)[0]++;
            }
            else {
                mp.put(c, new int[]{1, 0});
            }
        }
        
       // loop to store frequency of str2 in the map
        for(int i = 0; i<str2.length(); i++) {
            char c = str2.charAt(i);
            if(mp.containsKey(c)) {
                mp.get(c)[1]++;
            }
            else {
                mp.put(c, new int[]{0, 1});
            }
        }
        
       // Variables to store the sum of frequency difference of each strings
        int f1 = 0, f2 = 0;
        // loop to calculate the difference in frequency for each character
        for(Map.Entry<Character, int[]> entry : mp.entrySet()) {
           if(entry.getValue()[0]>entry.getValue()[1])
            f1+=(entry.getValue()[0] - entry.getValue()[1]);
           else
             f2+=(entry.getValue()[1] - entry.getValue()[0]);
        }
         
        // divide the answer by 2 since each change is counted 2 times.
        return Math.max(f1, f2);
    }
 
    // Driver code
    public static void main(String[] args) {
        // Two strings taken
        String str1 = "geeksforgeeks";
        String str2 = "geeksforcoder";
       
       // Output
        System.out.println(cntMinEdit(str1, str2));
       
      // Example 2
        str1 = "geeks";
         str2 = "keeg";
       
       // Output
        System.out.println(cntMinEdit(str1, str2));
    }
}


Python




# python code for above approach
 
def CntMinEdit(str1, str2):
    
    # vairable to store the answer
    ans = 0
     
   # map to store the frequency
    mp = {}
     
    # Loop to store frequency of str1 in the dictionary
    for char in str1:
        if char in mp:
            mp[char][0] += 1
        else:
            mp[char] = [1, 0]
     
    # Loop to store frequency of str2 in the dictionary
    for char in str2:
        if char in mp:
            mp[char][1] += 1
        else:
            mp[char] = [0, 1]
     
    # Variables to store the sum of frequency difference of each string
    f1, f2 = 0, 0
     
    # Loop to calculate the difference in frequency for each character
    for char, freq in mp.items():
        if freq[0] > freq[1]:
            f1 += freq[0] - freq[1]
        else:
            f2 += freq[1] - freq[0]
     
    # Return the max of f1 and f2
    return max(f1, f2)
 
# Driver code
if __name__ == "__main__":
    # Two strings taken
    str1 = "geeksforgeeks"
    str2 = "geeksforcoder"
     
    # Printing the output
    print(CntMinEdit(str1, str2))
   
    # Example 2
    str1 = "geeks"
    str2 = "keeg"
    print(CntMinEdit(str1, str2))


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // function to find the minimum no. of edits required.
    static int CntMinEdit(string str1, string str2)
    {
        // dictionary to store the frequency of each character in both strings
        Dictionary<char, Tuple<int, int>> mp = new Dictionary<char, Tuple<int, int>>();
 
        // loop to store frequency of str1 in the dictionary
        foreach (char c in str1)
        {
            if (!mp.ContainsKey(c))
                mp = new Tuple<int, int>(0, 0);
            mp = Tuple.Create(mp.Item1 + 1, mp.Item2);
        }
 
        // loop to store frequency of str2 in the dictionary
        foreach (char c in str2)
        {
            if (!mp.ContainsKey(c))
                mp = new Tuple<int, int>(0, 0);
            mp = Tuple.Create(mp.Item1, mp.Item2 + 1);
        }
 
        // Variables to store the sum of frequency difference of each strings
        int f1 = 0, f2 = 0;
 
        // loop to calculate the difference in frequency for each character
        foreach (var kvp in mp)
        {
            if (kvp.Value.Item1 > kvp.Value.Item2)
                f1 += kvp.Value.Item1 - kvp.Value.Item2;
            else
                f2 += kvp.Value.Item2 - kvp.Value.Item1;
        }
 
        // return max of f1 and f2
        return Math.Max(f2, f1);
    }
 
    // Driver code
    static void Main(string[] args)
    {
        // Two strings taken
        string str1 = "geeksforgeeks";
        string str2 = "geeksforcoder";
 
        // printing the output
        Console.WriteLine(CntMinEdit(str1, str2));
 
        // Example 2
        str1 = "geeks";
        str2 = "keeg";
        Console.WriteLine(CntMinEdit(str1, str2));
    }
}


Javascript




// Function to find the minimum number of edits required.
function countMinEdit(str1, str2) {
    // Counter variable
    let ans = 0;
 
    // Map to store the frequency of each character in both strings
    const mp = new Map();
 
    // Loop to store frequency of str1 in the map
    for (let i = 0; i < str1.length; i++) {
        if (!mp.has(str1[i])) {
            mp.set(str1[i], { first: 1, second: 0 });
        } else {
            mp.get(str1[i]).first++;
        }
    }
 
    // Loop to store frequency of str2 in the map
    for (let i = 0; i < str2.length; i++) {
        if (!mp.has(str2[i])) {
            mp.set(str2[i], { first: 0, second: 1 });
        } else {
            mp.get(str2[i]).second++;
        }
    }
 
    // Variables to store the sum of frequency difference of each string
    let f1 = 0, f2 = 0;
 
    // Loop to calculate the difference in frequency for each character
    for (const [key, value] of mp.entries()) {
        if (value.first > value.second) {
            f1 += value.first - value.second;
        } else {
            f2 += value.second - value.first;
        }
    }
 
    // Return the maximum of f1 and f2
    return Math.max(f2, f1);
}
 
// Driver code
// Example 1
let str1 = "geeksforgeeks";
let str2 = "geeksforcoder";
console.log(countMinEdit(str1, str2));
 
// Example 2
str1 = "geeks";
str2 = "keeg";
console.log(countMinEdit(str1, str2));


Output

4
1






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



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