Minimum number of given operations required to make two strings equal

Given two strings A and B, both strings contain characters a and b and are of equal lengths. There is one _ (empty space) in both the strings. The task is to convert first string into second string by doing the minimum number of the following operations:

  1. If _ is at position i then _ can be swapped with a character at position i+1 or i-1.
  2. If characters at positions i+1 and i+2 are different then _ can be swapped with a character at position i+1 or i+2.
  3. Similarly, if characters at positions i-1 and i-2 are different then _ can be swapped with a character at position i-1 or i-2.

Examples:

Input: A = “aba_a”, B = “_baaa”
Output: 2
Move 1 : A = “ab_aa” (Swapped A[2] with A[3])
Move 2 : A = “_baaa” (Swapped A[0] with A[2])

Input: A = “a_b”, B = “ab_”
Output: 1

Source: Directi Interview Set 7

Approach:

  • Apply a simple Breadth First Search over the string and an element of the queue used for BFS will contain the pair str, pos where pos is the position of _ in the string str.
  • Also maintain a map vis which will store the string as key and the minimum moves to get to the string as value.
  • For every string str from the queue, generate a new string tmp based on the four conditions given and update the vis map as vis[tmp] = vis[str] + 1.
  • Repeat the above steps until the queue is empty or the required string is generated i.e. tmp == B
  • If the required string is generated then return vis[str] + 1 which is the minimum number of operations required to change A to B.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return minimum number of
// operations to convert string A to B
int minOperations(string s, string f)
{
    unordered_map<string, int> vis;
  
    int n;
  
    n = s.length();
    int pos = 0;
    for (int i = 0; i < s.length(); i++) {
        if (s[i] == '_') {
  
            // store the position of '_'
            pos = i;
            break;
        }
    }
  
    // to store the generated string at every
    // move and the position of '_' within it
    queue<pair<string, int> > q;
  
    q.push({ s, pos });
  
    // vis will store the minimum operations
    // to reach that particular string
    vis[s] = 0;
  
    while (!q.empty()) {
        string ss = q.front().first;
        int pp = q.front().second;
  
        // minimum moves to reach the string ss
        int dist = vis[ss];
        q.pop();
  
        // try all 4 possible operations
  
        // if '_' can be swapped with
        // the character on it's left
        if (pp > 0) {
  
            // swap with the left character
            swap(ss[pp], ss[pp - 1]);
  
            // if the string is generated
            // for the first time
            if (!vis.count(ss)) {
  
                // if generated string is
                // the required string
                if (ss == f) {
                    return dist + 1;
                    break;
                }
  
                // update the distance for the
                // currently generated string
                vis[ss] = dist + 1;
                q.push({ ss, pp - 1 });
            }
  
            // restore the string before it was
            // swapped to check other cases
            swap(ss[pp], ss[pp - 1]);
        }
  
        // swap '_' with the character
        // on it's right this time
        if (pp < n - 1) {
            swap(ss[pp], ss[pp + 1]);
            if (!vis.count(ss)) {
                if (ss == f) {
                    return dist + 1;
                    break;
                }
                vis[ss] = dist + 1;
                q.push({ ss, pp + 1 });
            }
            swap(ss[pp], ss[pp + 1]);
        }
  
        // if '_' can be swapped
        // with the character 'i+2'
        if (pp > 1 && ss[pp - 1] != ss[pp - 2]) {
            swap(ss[pp], ss[pp - 2]);
            if (!vis.count(ss)) {
                if (ss == f) {
                    return dist + 1;
                    break;
                }
                vis[ss] = dist + 1;
                q.push({ ss, pp - 2 });
            }
            swap(ss[pp], ss[pp - 2]);
        }
  
        // if '_' can be swapped
        // with the character at 'i+2'
        if (pp < n - 2 && ss[pp + 1] != ss[pp + 2]) {
            swap(ss[pp], ss[pp + 2]);
            if (!vis.count(ss)) {
                if (ss == f) {
                    return dist + 1;
                    break;
                }
                vis[ss] = dist + 1;
                q.push({ ss, pp + 2 });
            }
            swap(ss[pp], ss[pp + 2]);
        }
    }
}
  
// Driver code
int main()
{
  
    string A = "aba_a";
    string B = "_baaa";
  
    cout << minOperations(A, B);
  
    return 0;
}

chevron_right


Output:

2


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.