Find the minimum number of preprocess moves required to make two strings equal

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:

  1. Choose any index i (0 ≤ i < n) and swap characters ai and bi.
  2. Choose any index i (0 ≤ i < n) and swap characters ai and an – i – 1.
  3. 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the minimum number of
// pre-processing moves required on string A
int Preprocess(string A, string B)
{
    // Length of the given strings
    int n = A.size();
  
    // To store the required answer
    int ans = 0;
  
    // Run a loop upto n/2
    for (int i = 0; i < n / 2; i++) {
  
        // To store frequency of 4 characters
        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 size is 4
        if (sz == 4)
            ans += 2;
  
        // If size is 3
        else if (sz == 3)
            ans += 1 + (A[i] == A[n - i - 1]);
  
        // If size is 2
        else if (sz == 2)
            ans += mp[A[i]] != 2;
    }
  
    // If n is odd
    if (n % 2 == 1 && A[n / 2] != B[n / 2])
        ans++;
  
    return ans;
}
  
// Driver code
int main()
{
    string A = "abacaba", B = "bacabaa";
    cout << Preprocess(A, B);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{
    // Function to return the minimum number of
    // pre-processing moves required on string A
    static int Preprocess(String A, String B)
    {
        // Length of the given strings
        int n = A.length();
      
        // To store the required answer
        int ans = 0;
      
        // Run a loop upto n/2
        for (int i = 0; i < n / 2; i++) 
        {
      
            // To store frequency of 4 characters
              
            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 size is 4
            if (sz == 4)
                ans += 2;
      
            // If size is 3
            else if (sz == 3)
                ans += 1 + (A.charAt(i) == A.charAt(n - i - 1) ? 1 : 0 );
      
            // If size is 2
            else if (sz == 2)
                ans += mp.get(A.charAt(i)) != 2 ? 1 : 0;
        }
      
        // If n is odd
        if (n % 2 == 1 && A.charAt(n / 2) != B.charAt(n / 2))
            ans++;
      
        return ans;
    }
      
    // Driver code
    public static void main (String[] args)
    {
        String A = "abacaba", B = "bacabaa";
        System.out.println(Preprocess(A, B));
      
    }
  
}
  
// This code is contributed by ihritik

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
  
# Function to return the minimum number of
# pre-processing moves required on string A
def Preprocess(A, B):
  
    # Length of the given strings
    n = len(A)
  
    # To store the required answer
    ans = 0
  
    # Run a loop upto n/2
    for i in range(n // 2):
  
        # To store frequency of 4 characters
        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 size is 4
        if (sz == 4):
            ans += 2
          
        # If size is 3    
        elif (sz == 3):
            ans += 1 + (A[i] == A[n - i - 1])
          
        # If size is 2
        elif (sz == 2):
            ans += mp[A[i]] != 2
      
    # If n is odd
    if (n % 2 == 1 and A[n // 2] != B[n // 2]):
        ans += 1
  
    return ans
  
# Driver code
A = "abacaba"
B = "bacabaa"
print(Preprocess(A, B))
  
# This code is contributed by Mohit Kumar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
  
class GFG
{
    // Function to return the minimum number of
    // pre-processing moves required on string A
    static int Preprocess(string A, string B)
    {
        // Length of the given strings
        int n = A.Length;
      
        // To store the required answer
        int ans = 0;
      
        // Run a loop upto n/2
        for (int i = 0; i < n / 2; i++) 
        {
      
            // To store frequency of 4 characters
              
            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 size is 4
            if (sz == 4)
                ans += 2;
      
            // If size is 3
            else if (sz == 3)
                ans += 1 + (A[i] == A[n - i - 1] ? 1 : 0 );
      
            // If size is 2
            else if (sz == 2)
                ans += mp[A[i]] != 2 ? 1 : 0;
        }
      
        // If n is odd
        if (n % 2 == 1 && A[n / 2] != B[n / 2])
            ans++;
      
        return ans;
    }
      
    // Driver code
    public static void Main ()
    {
        string A = "abacaba", B = "bacabaa";
        Console.WriteLine(Preprocess(A, B));
      
    }
}
  
// This code is contributed by ihritik

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach 
  
// Function to return the minimum number of 
// pre-processing moves required on string A 
function Preprocess($A, $B
      
    // Length of the given strings 
    $n = strlen($A); 
  
    // To store the required answer 
    $ans = 0; 
  
    // To store frequency of 4 characters 
    $mp = array(); 
      
    for($i = 0; $i < $n ; $i++)
        $mp[$A[$i]] = 0;
              
    // Run a loop upto n/2 
    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 size is 4 
        if ($sz == 4) 
            $ans += 2; 
  
        // If size is 3 
        else if ($sz == 3) 
            if($A[$i] == $A[$n - $i - 1])
                $ans += 1;
            else
                $ans += 1;
  
        // If size is 2 
        else if ($sz == 2) 
            $ans += $mp[$A[$i]] != 2; 
    }
      
    // If n is odd 
    if ($n % 2 == 1 && ($A[floor($n / 2)] != 
                        $B[floor($n / 2)])) 
        $ans++; 
  
    return $ans
  
// Driver code 
$A = "abacaba";
$B = "bacabaa"
echo Preprocess($A, $B); 
  
// This code is contributed by Ryuga
?>

chevron_right


Output:

4


My Personal Notes arrow_drop_up

pawanasipugmailcom

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.