Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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:
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:
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++




// 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;
}


Java




// 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


Python3




# 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


C#




// 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


PHP




<?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
?>


Javascript




<script>
  
// Javascript 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
    let n = A.length;
    
    // To store the required answer
    let ans = 0;
    
    // Run a loop upto n/2
    for(let i = 0; i < n / 2; i++) 
    {
          
        // To store frequency of 4 characters
        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 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.get(A[i]) != 2 ? 1 : 0;
    }
    
    // If n is odd
    if (n % 2 == 1 && A[(Math.floor(n / 2))] != 
                      B[(Math.floor(n / 2))])
        ans++;
    
    return ans;
}
  
// Driver code
let A = "abacaba", B = "bacabaa";
document.write(Preprocess(A, B));
  
// This code is contributed by unknown2108
  
</script>


Output: 

4

 

Time complexity: O(N) where N is the length of strings
Auxiliary space: O(1) because it is using constant extra space



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