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:
- If _ is at position i then _ can be swapped with a character at position i+1 or i-1.
- 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.
- 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:
C++
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std; // Function to return the minimum number of // operations to convert string A to B int minOperations(string s, string f) { // If both the strings are equal then // no operation needs to be performed if (s == f) return 0; 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; } |
Python3
# Python3 implementation of the approach from collections import deque # Function to return the minimum number of # operations to convert string A to B def minOperations(s: str , f: str ) - > int : # If both the strings are equal then # no operation needs to be performed if s = = f: return 0 vis = dict () n = len (s) pos = 0 for i in range (n): if s[i] = = '_' : # store the position of '_' pos = i break # to store the generated string at every # move and the position of '_' within it q = deque() q.append((s, pos)) # vis will store the minimum operations # to reach that particular string vis[s] = 0 while q: ss = q[ 0 ][ 0 ] pp = q[ 0 ][ 1 ] # minimum moves to reach the string ss dist = vis[ss] q.popleft() ss = list (ss) # try all 4 possible operations # if '_' can be swapped with # the character on it's left if pp > 0 : # swap with the left character ss[pp], ss[pp - 1 ] = ss[pp - 1 ], ss[pp] ss = ''.join(ss) # if the string is generated # for the first time if ss not in vis: # if generated string is # the required string if ss = = f: return dist + 1 # update the distance for the # currently generated string vis[ss] = dist + 1 q.append((ss, pp - 1 )) ss = list (ss) # restore the string before it was # swapped to check other cases ss[pp], ss[pp - 1 ] = ss[pp - 1 ], ss[pp] ss = ''.join(ss) # swap '_' with the character # on it's right this time if pp < n - 1 : ss = list (ss) ss[pp], ss[pp + 1 ] = ss[pp + 1 ], ss[pp] ss = ''.join(ss) if ss not in vis: if ss = = f: return dist + 1 vis[ss] = dist + 1 q.append((ss, pp + 1 )) ss = list (ss) ss[pp], ss[pp + 1 ] = ss[pp + 1 ], ss[pp] ss = ''.join(ss) # if '_' can be swapped # with the character 'i+2' if pp > 1 and ss[pp - 1 ] ! = ss[pp - 2 ]: ss = list (ss) ss[pp], ss[pp - 2 ] = ss[pp - 2 ], ss[pp] ss = ''.join(ss) if ss not in vis: if ss = = f: return dist + 1 vis[ss] = dist + 1 q.append((ss, pp - 2 )) ss = list (ss) ss[pp], ss[pp - 2 ] = ss[pp - 2 ], ss[pp] ss = ''.join(ss) # if '_' can be swapped # with the character at 'i+2' if pp < n - 2 and ss[pp + 1 ] ! = ss[pp + 2 ]: ss = list (ss) ss[pp], ss[pp + 2 ] = ss[pp + 2 ], ss[pp] ss = ''.join(ss) if ss not in vis: if ss = = f: return dist + 1 vis[ss] = dist + 1 q.append((ss, pp + 2 )) ss = list (ss) ss[pp], ss[pp + 2 ] = ss[pp + 2 ], ss[pp] ss = ''.join(ss) # Driver Code if __name__ = = "__main__" : A = "aba_a" B = "_baaa" print (minOperations(A, B)) # This code is contributed by # sanjeev2552 |
Output
2
Please Login to comment...