Check if two non-duplicate strings can be made equal after at most two swaps in one string - GeeksforGeeks

16 Mar, 2022
Given two strings A and B consisting of unique lowercase letters, the task is to check if both these strings can be made equal by using at most two swaps. Print Yes if they can. Otherwise, print No.
Example:
Input: A=”abcd”, B=”badc”Output: YesFirst swap a and b, and then swap c and d, in string A.Input: A=”abcd”, B=”cbda”Output: No
Approach: In this problem, string A can only be converted to string B if:
Case 1: If A is already equal to B.Case 2: If the number of differences in both the strings is less than equal to 3 and both the strings contains same character. Then its always possible to create B from A.Case 3: If the number of differences is 4 and all the swapping pairs in string A are same and opposite in string B.
Now to solve this problem, follow the below steps:
First, check if both the strings are already equal or not. If they are, then print Yes.Also, check if the size of both the string are equal or not. If it isn’t then print No.Create a vector, say b and store the indexes of character in string B.Create two maps, stay mp1 and mp2 to store the frequency of characters in strings A and B respectively.Now, check if the number of differences is less than or equal to 3, and both the maps, mp1 and mp2 have the same entries. If yes, then both the string can be made equal. So, print Yes.Also, both the strings can be made equal if they have 4 differences, but if it is a pair of two mirrored mistakes. So, print Yes if the differences are mirrored in two pairs.Otherwise, print No in the end.
First, check if both the strings are already equal or not. If they are, then print Yes.
Also, check if the size of both the string are equal or not. If it isn’t then print No.
Create a vector, say b and store the indexes of character in string B.
Create two maps, stay mp1 and mp2 to store the frequency of characters in strings A and B respectively.
Now, check if the number of differences is less than or equal to 3, and both the maps, mp1 and mp2 have the same entries. If yes, then both the string can be made equal. So, print Yes.
Also, both the strings can be made equal if they have 4 differences, but if it is a pair of two mirrored mistakes. So, print Yes if the differences are mirrored in two pairs.
Otherwise, print No in the end.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ code for the above approach #include <bits/stdc++.h>using namespace std; // Function to check if two strings can be made// equal using at most two swapsbool canBecomeEqual(string A, string B){     if (A.size() != B.size()) {        return 0;    }     // Case 1:    if (A == B) {        return 1;    }     // Vector to store the index of characters    // in B    vector<int> b(26, -1);     for (int i = 0; i < A.size(); i++) {        b[B[i] - 'a'] = i;    }     // Map to store the characters    // with their frequencies    unordered_map<char, int> mp1, mp2;     // Variable to store    // the total number of differences    int diff = 0;     // Set to store the the pair of indexes    // having changes in A wrt to B    set<pair<int, int> > positions;     for (int i = 0; i < A.size(); ++i) {        if (A[i] != B[i]) {            positions.insert({ i, b[A[i] - 'a'] });            diff++;        }        mp1[A[i]]++;        mp2[B[i]]++;    }     // Case 2:    if (diff <= 3 and mp1 == mp2) {        return 1;    }     // Case 3:    if (diff == 4 and mp1 == mp2) {        for (auto x : positions) {            pair<int, int> search                = { x.second, x.first };             if (positions.find(search)                == positions.end()) {                return 0;            }        }        return 1;    }     return 0;} // Driver Codeint main(){    string A = "abcd";    string B = "cdba";     if (canBecomeEqual(A, B)) {        cout << "Yes" << endl;    }    else {        cout << "No" << endl;    }}
// Java code for the above approachimport java.util.*; class GFG{    static class pair    {        int first, second;        public pair(int first, int second)         {            this.first = first;            this.second = second;        }        @Override        public int hashCode() {            final int prime = 31;            int result = 1;            result = prime * result + first;            result = prime * result + second;            return result;        }        @Override        public boolean equals(Object obj) {            if (this == obj)                return true;            if (obj == null)                return false;            if (getClass() != obj.getClass())                return false;            pair other = (pair) obj;            if (first != other.first)                return false;            if (second != other.second)                return false;            return true;        }                }   // Function to check if two Strings can be made// equal using at most two swapsstatic boolean canBecomeEqual(String A, String B){     if (A.length() != B.length()) {        return false;    }     // Case 1:    if (A == B) {        return true;    }     // Vector to store the index of characters    // in B    int []b = new int[26];     for (int i = 0; i < A.length(); i++) {        b[B.charAt(i) - 'a'] = i;    }     // Map to store the characters    // with their frequencies    HashMap<Character,Integer> mp1, mp2;    mp1 = new HashMap<Character,Integer>();    mp2 = new HashMap<Character,Integer>();       // Variable to store    // the total number of differences    int diff = 0;     // Set to store the the pair of indexes    // having changes in A wrt to B    HashSet<pair> positions = new HashSet<pair>();     for (int i = 0; i < A.length(); ++i) {        if (A.charAt(i) != B.charAt(i)) {            positions.add(new pair(i, b[A.charAt(i) - 'a'] ));            diff++;        }        if(mp1.containsKey(A.charAt(i))){            mp1.put(A.charAt(i), mp1.get(A.charAt(i))+1);        }        else{            mp1.put(A.charAt(i), 1);        }        if(mp2.containsKey(B.charAt(i))){            mp2.put(B.charAt(i), mp2.get(B.charAt(i))+1);        }        else{            mp2.put(B.charAt(i), 1);        }    }     // Case 2:    if (diff <= 3 && mp1 == mp2) {        return true;    }     // Case 3:    if (diff == 4 && mp1 == mp2) {        for (pair x : positions) {            pair search                = new pair( x.second, x.first );             if (!positions.contains(search)) {                return false;            }        }        return true;    }     return false;} // Driver Codepublic static void main(String[] args){    String A = "abcd";    String B = "cdba";     if (canBecomeEqual(A, B)) {        System.out.print("Yes" +"\n");    }    else {        System.out.print("No" +"\n");    }}} // This code is contributed by 29AjayKumar
# python3 code for the above approach # Function to check if two strings can be made# equal using at most two swapsdef canBecomeEqual(A, B):     if (len(A) != len(B)):        return 0         # Case 1:    if (A == B):        return 1         # Vector to store the index of characters        # in B    b = [-1 for _ in range(26)]     for i in range(0, len(A)):        b[ord(B[i]) - ord('a')] = i         # Map to store the characters        # with their frequencies    mp1 = {}    mp2 = {}     # Variable to store    # the total number of differences    diff = 0     # Set to store the the pair of indexes    # having changes in A wrt to B    positions = set()     for i in range(0, len(A)):        if (A[i] != B[i]):            positions.add((i, b[ord(A[i]) - ord('a')]))            diff += 1        if A[i] in mp1:            mp1[A[i]] += 1        else:            mp1[A[i]] = 1         if B[i] in mp2:            mp2[B[i]] += 1        else:            mp2[B[i]] = 1         # Case 2:    if (diff <= 3 and mp1 == mp2):        return 1         # Case 3:    if (diff == 4 and mp1 == mp2):        for x in positions:            search = (x[1], x[0])            if (not (search in positions)):                return 0         return 1     return 0 # Driver Codeif __name__ == "__main__":     A = "abcd"    B = "cdba"     if (canBecomeEqual(A, B)):        print("Yes")     else:        print("No")     # This code is contributed by rakeshsahni
// C# code for the above approachusing System;using System.Collections.Generic; public class GFG{  class pair : IComparable<pair>  {    public int first, second;    public pair(int first, int second)    {      this.first = first;      this.second = second;    }    public int CompareTo(pair p)    {      return this.second-p.first;    }  }   // Function to check if two Strings can be made  // equal using at most two swaps  static bool canBecomeEqual(String A, String B)  {     if (A.Length != B.Length) {      return false;    }     // Case 1:    if (A == B) {      return true;    }     // List to store the index of characters    // in B    int []b = new int[26];     for (int i = 0; i < A.Length; i++) {      b[B[i] - 'a'] = i;    }     // Map to store the characters    // with their frequencies    Dictionary<char,int> mp1, mp2;    mp1 = new Dictionary<char,int>();    mp2 = new Dictionary<char,int>();     // Variable to store    // the total number of differences    int diff = 0;     // Set to store the the pair of indexes    // having changes in A wrt to B    HashSet<pair> positions = new HashSet<pair>();     for (int i = 0; i < A.Length; ++i) {      if (A[i] != B[i]) {        positions.Add(new pair(i, b[A[i] - 'a'] ));        diff++;      }      if(mp1.ContainsKey(A[i])){        mp1[A[i]] = mp1[A[i]]+1;      }      else{        mp1.Add(A[i], 1);      }      if(mp2.ContainsKey(B[i])){        mp2[B[i]] = mp2[B[i]]+1;      }      else{        mp2.Add(B[i], 1);      }    }     // Case 2:    if (diff <= 3 && mp1 == mp2) {      return true;    }     // Case 3:    if (diff == 4 && mp1 == mp2) {      foreach (pair x in positions) {        pair search          = new pair( x.second, x.first );         if (!positions.Contains(search)) {          return false;        }      }      return true;    }     return false;  }   // Driver Code  public static void Main(String[] args)  {    String A = "abcd";    String B = "cdba";     if (canBecomeEqual(A, B)) {      Console.Write("Yes" +"\n");    }    else {      Console.Write("No" +"\n");    }  }} // This code is contributed by shikhasingrajput
<script> // JavaScript code for the above approach // Function to check if two strings can be made// equal using at most two swapsfunction canBecomeEqual(A, B){     if (A.length != B.length)        return 0     // Case 1:    if (A.B)        return 1     // Vector to store the index of characters    // in B    let b = new Array(26).fill(-1)     for(let i=0;i<A.length;i++){        b[B.charCodeAt(i) - 'a'.charCodeAt(0)] = i    }     // Map to store the characters    // with their frequencies    let mp1 = new Map()    let mp2 = new Map() // Variable to store// the total number of differences    diff = 0 // Set to store the the pair of indexes// having changes in A wrt to B    let positions = new Set()     for(let i=0;i<A.length;i++){        if (A[i] != B[i]){            positions.add([i, b[A.charCodeAt(i) - 'a'.charCodeAt(0)]])            diff += 1        }        if(mp1.has(A[i]))            mp1.set(A[i],mp1.get(A[i])+1)        else            mp1.set(A[i],1)         if(mp2.has(B[i]))            mp2.set(B[i],mp2.get(B[i])+1)        else            mp2.set(B[i],1)    }     // Case 2:    if (diff <= 3 && mp1 == mp2)        return 1     // Case 3:    if (diff == 4 && mp1 == mp2){        for(let x of positions){            search = [x[1], x[0]]            if (!positions.has(search))                return 0        }         return 1    }     return 0}// Driver Code let A = "abcd"let B = "cdba" if (canBecomeEqual(A, B))    document.write("Yes") else    document.write("No") // This code is contributed by shinjanpatra </script>
  
No
 
Time Complexity: O(N*log N)Auxiliary Space: O(N)
 
29AjayKumar
rakeshsahni
shikhasingrajput
shinjanpatra
Swap-Program
Strings
Strings
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Top 50 String Coding Problems for Interviews
Minimum changes to a string to make all substrings distinct
Hill Cipher
Vigenère Cipher
Naive algorithm for Pattern Searching
How to Append a Character to a String in C
Convert character array to string in C++
Converting Roman Numerals to Decimal lying between 1 to 3999
sprintf() in C
Print all subsequences of a string