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:
- Insert a character into the string.
- Remove a character from the string.
- 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:
- Initialize two arrays, say freq1[] and freq2[] to store the frequency of all the characters of str1 and str2 respectively.
- Traverse both the strings and store the frequency of each character of both the strings in arrays freq1[] and freq2[] respectively.
- Traverse both the arrays freq1[] and freq2[].
- 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.
- 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++
#include <bits/stdc++.h>
using namespace std;
int ctMinEdits(string str1, string str2)
{
int N1 = str1.length();
int N2 = str2.length();
int freq1[256] = { 0 };
for ( int i = 0; i < N1; i++) {
freq1[str1[i]]++;
}
int freq2[256] = { 0 };
for ( int i = 0; i < N2; i++) {
freq2[str2[i]]++;
}
for ( int i = 0; i < 256; i++) {
if (freq1[i] > freq2[i]) {
freq1[i] = freq1[i]
- freq2[i];
freq2[i] = 0;
}
else {
freq2[i] = freq2[i]
- freq1[i];
freq1[i] = 0;
}
}
int sum1 = 0;
int sum2 = 0;
for ( int i = 0; i < 256; i++) {
sum1 += freq1[i];
sum2 += freq2[i];
}
return max(sum1, sum2);
}
int main()
{
string str1 = "geeksforgeeks" ;
string str2 = "geeksforcoder" ;
cout << ctMinEdits(str1, str2);
}
|
Java
import java.util.*;
import java.io.*;
import java.lang.Math;
class GFG{
static int ctMinEdits(String str1, String str2)
{
int N1 = str1.length();
int N2 = str2.length();
int freq1[] = new int [ 256 ];
Arrays.fill(freq1, 0 );
for ( int i = 0 ; i < N1; i++)
{
freq1[str1.charAt(i)]++;
}
int freq2[] = new int [ 256 ];
Arrays.fill(freq2, 0 );
for ( int i = 0 ; i < N2; i++)
{
freq2[str2.charAt(i)]++;
}
for ( int i = 0 ; i < 256 ; i++)
{
if (freq1[i] > freq2[i])
{
freq1[i] = freq1[i] - freq2[i];
freq2[i] = 0 ;
}
else
{
freq2[i] = freq2[i] - freq1[i];
freq1[i] = 0 ;
}
}
int sum1 = 0 ;
int sum2 = 0 ;
for ( int i = 0 ; i < 256 ; i++)
{
sum1 += freq1[i];
sum2 += freq2[i];
}
return Math.max(sum1, sum2);
}
public static void main( final String[] args)
{
String str1 = "geeksforgeeks" ;
String str2 = "geeksforcoder" ;
System.out.println(ctMinEdits(str1, str2));
}
}
|
Python3
def ctMinEdits(str1, str2):
N1 = len (str1)
N2 = len (str2)
freq1 = [ 0 ] * 256
for i in range (N1):
freq1[ ord (str1[i])] + = 1
freq2 = [ 0 ] * 256
for i in range (N2):
freq2[ ord (str2[i])] + = 1
for i in range ( 256 ):
if (freq1[i] > freq2[i]):
freq1[i] = freq1[i] - freq2[i]
freq2[i] = 0
else :
freq2[i] = freq2[i] - freq1[i]
freq1[i] = 0
sum1 = 0
sum2 = 0
for i in range ( 256 ):
sum1 + = freq1[i]
sum2 + = freq2[i]
return max (sum1, sum2)
str1 = "geeksforgeeks"
str2 = "geeksforcoder"
print (ctMinEdits(str1, str2))
|
C#
using System;
class GFG{
static int ctMinEdits( string str1, string str2)
{
int N1 = str1.Length;
int N2 = str2.Length;
int [] freq1 = new int [256];
freq1[0] = str1[0];
for ( int i = 0; i < N1; i++)
{
freq1[str1[i]]++;
}
int [] freq2 = new int [256];
freq2[0] = str2[0];
for ( int i = 0; i < N2; i++)
{
freq2[str2[i]]++;
}
for ( int i = 0; i < 256; i++)
{
if (freq1[i] > freq2[i])
{
freq1[i] = freq1[i] - freq2[i];
freq2[i] = 0;
}
else
{
freq2[i] = freq2[i] - freq1[i];
freq1[i] = 0;
}
}
int sum1 = 0;
int sum2 = 0;
for ( int i = 0; i < 256; i++)
{
sum1 += freq1[i];
sum2 += freq2[i];
}
return Math.Max(sum1, sum2);
}
public static void Main()
{
string str1 = "geeksforgeeks" ;
string str2 = "geeksforcoder" ;
Console.WriteLine(ctMinEdits(str1, str2));
}
}
|
Javascript
<script>
function ctMinEdits(str1, str2)
{
let N1 = str1.length;
let N2 = str2.length;
let freq1 = new Array(256).fill(0);
for (let i = 0; i < N1; i++)
{
freq1[str1[i].charCodeAt()]++;
}
let freq2 = new Array(256).fill(0);
for (let i = 0; i < N2; i++)
{
freq2[str2[i].charCodeAt()]++;
}
for (let i = 0; i < 256; i++)
{
if (freq1[i] > freq2[i])
{
freq1[i] = freq1[i] - freq2[i];
freq2[i] = 0;
}
else
{
freq2[i] = freq2[i] - freq1[i];
freq1[i] = 0;
}
}
let sum1 = 0;
let sum2 = 0;
for (let i = 0; i < 256; i++)
{
sum1 += freq1[i];
sum2 += freq2[i];
}
return Math.max(sum1, sum2);
}
let str1 = "geeksforgeeks" ;
let str2 = "geeksforcoder" ;
document.write(ctMinEdits(str1.split( '' ), str2.split( '' )));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int CntMinEdit(string str1, string str2)
{
int ans = 0;
unordered_map< char ,pair< int , int >>mp;
for ( int i = 0; i<str1.length();i++)
mp[str1[i]].first++;
for ( int i = 0; i<str2.length();i++)
mp[str2[i]].second++;
int f1 = 0, f2 = 0;
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(f2,f1);
}
int main()
{
string str1 = "geeksforgeeks" ;
string str2 = "geeksforcoder" ;
cout << CntMinEdit(str1, str2)<<endl;
str1 = "geeks" ;
str2 = "keeg" ;
cout << CntMinEdit(str1, str2)<<endl;
}
|
Java
import java.util.*;
public class Main {
public static int cntMinEdit(String str1, String str2) {
int ans = 0 ;
HashMap<Character, int []> mp = new HashMap<>();
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 });
}
}
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 });
}
}
int f1 = 0 , f2 = 0 ;
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 ]);
}
return Math.max(f1, f2);
}
public static void main(String[] args) {
String str1 = "geeksforgeeks" ;
String str2 = "geeksforcoder" ;
System.out.println(cntMinEdit(str1, str2));
str1 = "geeks" ;
str2 = "keeg" ;
System.out.println(cntMinEdit(str1, str2));
}
}
|
Python
def CntMinEdit(str1, str2):
ans = 0
mp = {}
for char in str1:
if char in mp:
mp[char][ 0 ] + = 1
else :
mp[char] = [ 1 , 0 ]
for char in str2:
if char in mp:
mp[char][ 1 ] + = 1
else :
mp[char] = [ 0 , 1 ]
f1, f2 = 0 , 0
for char, freq in mp.items():
if freq[ 0 ] > freq[ 1 ]:
f1 + = freq[ 0 ] - freq[ 1 ]
else :
f2 + = freq[ 1 ] - freq[ 0 ]
return max (f1, f2)
if __name__ = = "__main__" :
str1 = "geeksforgeeks"
str2 = "geeksforcoder"
print (CntMinEdit(str1, str2))
str1 = "geeks"
str2 = "keeg"
print (CntMinEdit(str1, str2))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int CntMinEdit( string str1, string str2)
{
Dictionary< char , Tuple< int , int >> mp = new Dictionary< char , Tuple< int , int >>();
foreach ( char c in str1)
{
if (!mp.ContainsKey(c))
mp = new Tuple< int , int >(0, 0);
mp = Tuple.Create(mp.Item1 + 1, mp.Item2);
}
foreach ( char c in str2)
{
if (!mp.ContainsKey(c))
mp = new Tuple< int , int >(0, 0);
mp = Tuple.Create(mp.Item1, mp.Item2 + 1);
}
int f1 = 0, f2 = 0;
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 Math.Max(f2, f1);
}
static void Main( string [] args)
{
string str1 = "geeksforgeeks" ;
string str2 = "geeksforcoder" ;
Console.WriteLine(CntMinEdit(str1, str2));
str1 = "geeks" ;
str2 = "keeg" ;
Console.WriteLine(CntMinEdit(str1, str2));
}
}
|
Javascript
function countMinEdit(str1, str2) {
let ans = 0;
const mp = new 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++;
}
}
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++;
}
}
let f1 = 0, f2 = 0;
for (const [key, value] of mp.entries()) {
if (value.first > value.second) {
f1 += value.first - value.second;
} else {
f2 += value.second - value.first;
}
}
return Math.max(f2, f1);
}
let str1 = "geeksforgeeks" ;
let str2 = "geeksforcoder" ;
console.log(countMinEdit(str1, str2));
str1 = "geeks" ;
str2 = "keeg" ;
console.log(countMinEdit(str1, str2));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
30 Oct, 2023
Like Article
Save Article