Find the minimum number of preprocess moves required to make two strings equal
Last Updated :
24 Mar, 2023
Given two strings A and B of equal lengths consisting of lower case English letters. The task is to count the minimum number of pre-processing moves on string A required to make it equal to string B after applying below operations:
- Choose any index i (0 ? i < n) and swap characters ai and bi.
- Choose any index i (0 ? i < n) and swap characters ai and an – i – 1.
- Choose any index i (0 ? i < n) and swap characters bi and bn – i – 1.
In one pre-process move you can replace a character in A with any other character of English alphabet.
Examples:
Input: A = “abacaba”, B = “bacabaa”
Output: 4
Preprocess moves are as follows:
Set A0 = ‘b’, A2 = ‘c’, A3 = ‘a’ and A4 = ‘b’ and A becomes “bbcabba”.
Then we can obtain equal strings by the following sequence of operations:
swap(A1, B1) and swap(A1, A5).
Input: A = “zcabd” B = “dbacz”
Output: 0
No preprocess moves are required.
We can use the following sequence of changes to make A and B equal:
swap(B0, B4) then swap(A1, A3).
Approach: Let’s divide all characters of both strings into groups in such a way that characters in each group can be swapped with each other with changes. So, there will be following groups: {A0, An – 1, B0, Bn – 1}, {A1, An – 2, B1, Bn – 2} and so on. Since these groups don’t affect each other, we can calculate the number of pre-processing moves in each group and then sum it up.
How to determine if a group does not need any pre-processing moves?
For a group consisting of 2 characters (there will be one such group if n is odd) that’s easy – If the characters in this group are equal, the answer is 0, otherwise, it’s 1.
To determine the required number of pre-processing moves for a group consisting of four characters, we may use the following fact: this group doesn’t require any pre-processing moves if the characters in this group can be divided into pairs. So if the group contains four equal characters or two pairs of equal characters, then the answer for this group is 0. Otherwise, we may check that replacing only one character of Ai and An – i – 1 will be enough. If so, then the answer is 1, otherwise, it’s 2.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int Preprocess(string A, string B)
{
int n = A.size();
int ans = 0;
for ( int i = 0; i < n / 2; i++) {
map< char , int > mp;
mp[A[i]]++;
mp[A[n - i - 1]]++;
mp[B[i]]++;
mp[B[n - i - 1]]++;
int sz = mp.size();
if (sz == 4)
ans += 2;
else if (sz == 3)
ans += 1 + (A[i] == A[n - i - 1]);
else if (sz == 2)
ans += mp[A[i]] != 2;
}
if (n % 2 == 1 && A[n / 2] != B[n / 2])
ans++;
return ans;
}
int main()
{
string A = "abacaba" , B = "bacabaa" ;
cout << Preprocess(A, B);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int Preprocess(String A, String B)
{
int n = A.length();
int ans = 0 ;
for ( int i = 0 ; i < n / 2 ; i++)
{
HashMap<Character, Integer> mp = new HashMap<>();
if (mp.containsKey(A.charAt(i)))
mp.put(A.charAt(i), mp.get(A.charAt(i))+ 1 );
else
mp.put(A.charAt(i), 1 );
if (mp.containsKey(A.charAt(n-i- 1 )))
mp.put(A.charAt(n-i- 1 ), mp.get(A.charAt(n-i- 1 ))+ 1 );
else
mp.put(A.charAt(n-i- 1 ), 1 );
if (mp.containsKey(B.charAt(i)))
mp.put(B.charAt(i), mp.get(B.charAt(i))+ 1 );
else
mp.put(B.charAt(i), 1 );
if (mp.containsKey(B.charAt(n-i- 1 )))
mp.put(B.charAt(n-i- 1 ), mp.get(B.charAt(n-i- 1 ))+ 1 );
else
mp.put(B.charAt(n-i- 1 ), 1 );
int sz = mp.size();
if (sz == 4 )
ans += 2 ;
else if (sz == 3 )
ans += 1 + (A.charAt(i) == A.charAt(n - i - 1 ) ? 1 : 0 );
else if (sz == 2 )
ans += mp.get(A.charAt(i)) != 2 ? 1 : 0 ;
}
if (n % 2 == 1 && A.charAt(n / 2 ) != B.charAt(n / 2 ))
ans++;
return ans;
}
public static void main (String[] args)
{
String A = "abacaba" , B = "bacabaa" ;
System.out.println(Preprocess(A, B));
}
}
|
Python3
def Preprocess(A, B):
n = len (A)
ans = 0
for i in range (n / / 2 ):
mp = dict ()
mp[A[i]] = 1
if A[i] = = A[n - i - 1 ]:
mp[A[n - i - 1 ]] + = 1
if B[i] in mp.keys():
mp[B[i]] + = 1
else :
mp[B[i]] = 1
if B[n - i - 1 ] in mp.keys():
mp[B[n - 1 - i]] + = 1
else :
mp[B[n - 1 - i]] = 1
sz = len (mp)
if (sz = = 4 ):
ans + = 2
elif (sz = = 3 ):
ans + = 1 + (A[i] = = A[n - i - 1 ])
elif (sz = = 2 ):
ans + = mp[A[i]] ! = 2
if (n % 2 = = 1 and A[n / / 2 ] ! = B[n / / 2 ]):
ans + = 1
return ans
A = "abacaba"
B = "bacabaa"
print (Preprocess(A, B))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int Preprocess( string A, string B)
{
int n = A.Length;
int ans = 0;
for ( int i = 0; i < n / 2; i++)
{
Dictionary< char , int > mp = new Dictionary< char , int >();
if (mp.ContainsKey(A[i]))
mp[A[i]]++;
else
mp[A[i]] = 1;
if (mp.ContainsKey(A[n-i-1]))
mp[A[n - i - 1]]++;
else
mp[A[n - i - 1]] = 1;
if (mp.ContainsKey(B[i]))
mp[B[i]]++;
else
mp[B[i]] = 1;
if (mp.ContainsKey(B[n-i-1]))
mp[B[n - i - 1]]++;
else
mp[B[n - i - 1]] = 1;
int sz = mp.Count;
if (sz == 4)
ans += 2;
else if (sz == 3)
ans += 1 + (A[i] == A[n - i - 1] ? 1 : 0 );
else if (sz == 2)
ans += mp[A[i]] != 2 ? 1 : 0;
}
if (n % 2 == 1 && A[n / 2] != B[n / 2])
ans++;
return ans;
}
public static void Main ()
{
string A = "abacaba" , B = "bacabaa" ;
Console.WriteLine(Preprocess(A, B));
}
}
|
PHP
<?php
function Preprocess( $A , $B )
{
$n = strlen ( $A );
$ans = 0;
$mp = array ();
for ( $i = 0; $i < $n ; $i ++)
$mp [ $A [ $i ]] = 0;
for ( $i = 0; $i < floor ( $n / 2); $i ++)
{
$mp [ $A [ $i ]]++;
$mp [ $A [ $n - $i - 1]]++;
$mp [ $B [ $i ]]++;
$mp [ $B [ $n - $i - 1]]++;
$sz = sizeof( $mp );
if ( $sz == 4)
$ans += 2;
else if ( $sz == 3)
if ( $A [ $i ] == $A [ $n - $i - 1])
$ans += 1;
else
$ans += 1;
else if ( $sz == 2)
$ans += $mp [ $A [ $i ]] != 2;
}
if ( $n % 2 == 1 && ( $A [ floor ( $n / 2)] !=
$B [ floor ( $n / 2)]))
$ans ++;
return $ans ;
}
$A = "abacaba" ;
$B = "bacabaa" ;
echo Preprocess( $A , $B );
?>
|
Javascript
<script>
function Preprocess(A, B)
{
let n = A.length;
let ans = 0;
for (let i = 0; i < n / 2; i++)
{
let mp = new Map();
if (mp.has(A[i]))
mp.set(A[i], mp.get(A[i]) + 1);
else
mp.set(A[i], 1);
if (mp.has(A[n - i - 1]))
mp.set(A[n - i - 1],
mp.get(A[n - i - 1]) + 1);
else
mp.set(A[n - i - 1], 1);
if (mp.has(B[i]))
mp.set(B[i], mp.get(B[i]) + 1);
else
mp.set(B[i], 1);
if (mp.has(B[n - i - 1]))
mp.set(B[n - i - 1],
mp.get(B[n - i - 1]) + 1);
else
mp.set(B[n - i - 1], 1);
let sz = mp.size;
if (sz == 4)
ans += 2;
else if (sz == 3)
ans += 1 + (A[i] ==
A[n - i - 1] ? 1 : 0);
else if (sz == 2)
ans += mp.get(A[i]) != 2 ? 1 : 0;
}
if (n % 2 == 1 && A[(Math.floor(n / 2))] !=
B[(Math.floor(n / 2))])
ans++;
return ans;
}
let A = "abacaba" , B = "bacabaa" ;
document.write(Preprocess(A, B));
</script>
|
Time complexity: O(N) where N is the length of strings
Auxiliary space: O(1) because it is using constant extra space
Share your thoughts in the comments
Please Login to comment...