Open In App

Transform Strings by Frequency Exchange and Swapping

Last Updated : 29 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given two strings s1 and s2, the task is to check if they can be transformed into each other by performing the following operation any number of times on any string.

  • Choosing any two characters that exist and exchanging their frequencies.
  • Swapping any characters

Example:

Input: s1 = “abc”, s2 = “bca”
Output: true
Explanation: s1 can be formed from s2 in 2 steps.
Step 1: “abc” -> “acb”
Step 2: “acb” -> “bca”

Input: s1 = “a”, s2 = “aa”
Output: false
Explanation: It is not possible to form s1 from s2, or vice versa, in any number of steps.

Input: s1 = “cabbba”, s2 = “abbccc”
Output: true
Explanation: s1 can be formed from s2 in 3 steps.
Step 1: “cabbba” -> “caabbb”
Step 2: “caabbb” -> “baaccc”
Step 3: “baaccc” -> “abbccc”

Approach:

Calculates the frequency of each character of strings using Hashing and then compares the frequencies to check if the strings can be converted. And since frequency of any two existing characters can be exchange, this means that overall the frequency of frequency must be remains same after performing operation any number of times. So, we also have to check if the frequency of each frequency is the same in both strings, otherwise return false

Steps-by-step approach:

  • Calculate the frequency of each character in both strings.
  • Count the frequency of each frequency in both strings.
  • Check if lengths are equals or not. If not then return false
  • Check every character in one string is present in the other string, otherwise return false
  • Check if the frequency of each frequency is the same in both strings, otherwise return false
  • Return true if all above checks pass.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to check if two strings are Converted
bool canConvert(string s1, string s2)
{
    // Create frequency maps for both strings
    unordered_map<char, int> freq1, freq2, unmap1, unmap2;
 
    // If the strings are of different lengths, they can't
    // be Converted
    if (s1.size() != s2.size())
        return false;
 
    // Calculate the frequency of each character in s1
    for (auto i : s1) {
        freq1[i]++;
    }
 
    // Calculate the frequency of each character in s2
    for (auto i : s2) {
        freq2[i]++;
    }
 
    // Count the frequency of each frequency in s2
    for (auto i : freq2) {
        unmap2[i.second]++;
    }
 
    // Count the frequency of each frequency in s1
    for (auto i : freq1) {
        unmap1[i.second]++;
    }
 
    // Check if every character in s1 is also in s2
    for (auto i : freq1) {
        if (freq2.find(i.first) == freq2.end())
            return false;
    }
 
    // Check if every character in s2 is also in s1
    for (auto i : freq2) {
        if (freq1.find(i.first) == freq1.end())
            return false;
    }
 
    // Check if the frequency of each frequency is the same
    // in both strings
    for (auto i : unmap1) {
        if (i.second != unmap2[i.first])
            return false;
    }
 
    // If all checks pass, the strings are Converted
    return true;
}
 
int main()
{
    string s1 = "cabbba";
    string s2 = "abbccc";
 
    // Print whether the strings are Converted
    cout << (canConvert(s1, s2) ? "True" : "False") << endl;
    return 0;
}


Java




import java.util.HashMap;
import java.util.Map;
 
public class StringConversion {
 
    // Function to check if two strings are Converted
    static boolean canConvert(String s1, String s2) {
        // Create frequency maps for both strings
        Map<Character, Integer> freq1 = new HashMap<>();
        Map<Character, Integer> freq2 = new HashMap<>();
        Map<Integer, Integer> unmap1 = new HashMap<>();
        Map<Integer, Integer> unmap2 = new HashMap<>();
 
        // If the strings are of different lengths, they can't be Converted
        if (s1.length() != s2.length())
            return false;
 
        // Calculate the frequency of each character in s1
        for (char i : s1.toCharArray()) {
            freq1.put(i, freq1.getOrDefault(i, 0) + 1);
        }
 
        // Calculate the frequency of each character in s2
        for (char i : s2.toCharArray()) {
            freq2.put(i, freq2.getOrDefault(i, 0) + 1);
        }
 
        // Count the frequency of each frequency in s2
        for (int i : freq2.values()) {
            unmap2.put(i, unmap2.getOrDefault(i, 0) + 1);
        }
 
        // Count the frequency of each frequency in s1
        for (int i : freq1.values()) {
            unmap1.put(i, unmap1.getOrDefault(i, 0) + 1);
        }
 
        // Check if every character in s1 is also in s2
        for (char i : freq1.keySet()) {
            if (!freq2.containsKey(i))
                return false;
        }
 
        // Check if every character in s2 is also in s1
        for (char i : freq2.keySet()) {
            if (!freq1.containsKey(i))
                return false;
        }
 
        // Check if the frequency of each frequency is the same in both strings
        for (Map.Entry<Integer, Integer> entry : unmap1.entrySet()) {
            int key = entry.getKey();
            if (!unmap2.containsKey(key) || !unmap2.get(key).equals(entry.getValue()))
                return false;
        }
 
        // If all checks pass, the strings are Converted
        return true;
    }
 
    public static void main(String[] args) {
        String s1 = "cabbba";
        String s2 = "abbccc";
 
        // Print whether the strings are Converted
        System.out.println(canConvert(s1, s2) ? "True" : "False");
    }
}


C#




using System;
using System.Collections.Generic;
 
class GFG
{
    // Function to check if two strings are Converted
    static bool CanConvert(string s1, string s2)
    {
        // Create frequency maps for both strings
        Dictionary<char, int> freq1 = new Dictionary<char, int>();
        Dictionary<char, int> freq2 = new Dictionary<char, int>();
        Dictionary<int, int> unmap1 = new Dictionary<int, int>();
        Dictionary<int, int> unmap2 = new Dictionary<int, int>();
 
        // If the strings are of different lengths, they can't
        // be Converted
        if (s1.Length != s2.Length)
            return false;
 
        // Calculate the frequency of each character in s1
        foreach (char i in s1)
        {
            if (freq1.ContainsKey(i))
                freq1[i]++;
            else
                freq1[i] = 1;
        }
 
        // Calculate the frequency of each character in s2
        foreach (char i in s2)
        {
            if (freq2.ContainsKey(i))
                freq2[i]++;
            else
                freq2[i] = 1;
        }
 
        // Count the frequency of each frequency in s2
        foreach (var i in freq2)
        {
            if (unmap2.ContainsKey(i.Value))
                unmap2[i.Value]++;
            else
                unmap2[i.Value] = 1;
        }
 
        // Count the frequency of each frequency in s1
        foreach (var i in freq1)
        {
            if (unmap1.ContainsKey(i.Value))
                unmap1[i.Value]++;
            else
                unmap1[i.Value] = 1;
        }
 
        // Check if every character in s1 is also in s2
        foreach (var i in freq1)
        {
            if (!freq2.ContainsKey(i.Key))
                return false;
        }
 
        // Check if every character in s2 is also in s1
        foreach (var i in freq2)
        {
            if (!freq1.ContainsKey(i.Key))
                return false;
        }
 
        // Check if the frequency of each frequency is the same
        // in both strings
        foreach (var i in unmap1)
        {
            if (!unmap2.ContainsKey(i.Key) || i.Value != unmap2[i.Key])
                return false;
        }
 
        // If all checks pass, the strings are Converted
        return true;
    }
 
    static void Main()
    {
        string s1 = "cabbba";
        string s2 = "abbccc";
 
        // Print whether the strings are Converted
        Console.WriteLine(CanConvert(s1, s2) ? "True" : "False");
    }
}


Javascript




// Function to check if two strings are converted
function canConvert(s1, s2) {
    // Create frequency maps for both strings
    let freq1 = new Map();
    let freq2 = new Map();
    let unmap1 = new Map();
    let unmap2 = new Map();
 
    // If the strings are of different lengths, they can't be converted
    if (s1.length !== s2.length)
        return false;
 
    // Calculate the frequency of each character in s1
    for (let i of s1) {
        freq1.set(i, (freq1.get(i) || 0) + 1);
    }
 
    // Calculate the frequency of each character in s2
    for (let i of s2) {
        freq2.set(i, (freq2.get(i) || 0) + 1);
    }
 
    // Count the frequency of each frequency in s2
    for (let i of freq2.values()) {
        unmap2.set(i, (unmap2.get(i) || 0) + 1);
    }
 
    // Count the frequency of each frequency in s1
    for (let i of freq1.values()) {
        unmap1.set(i, (unmap1.get(i) || 0) + 1);
    }
 
    // Check if every character in s1 is also in s2
    for (let i of freq1.keys()) {
        if (!freq2.has(i))
            return false;
    }
 
    // Check if every character in s2 is also in s1
    for (let i of freq2.keys()) {
        if (!freq1.has(i))
            return false;
    }
 
    // Check if the frequency of each frequency is the same in both strings
    for (let [key, value] of unmap1.entries()) {
        if (!unmap2.has(key) || unmap2.get(key) !== value)
            return false;
    }
 
    // If all checks pass, the strings are converted
    return true;
}
 
// Main function
function main() {
    let s1 = "cabbba";
    let s2 = "abbccc";
 
    // Print whether the strings are converted
    console.log(canConvert(s1, s2) ? "True" : "False");
}
 
// Call the main function
main();


Python3




# Python Implementation
 
def canConvert(s1, s2):
    # Create frequency dictionaries for both strings
    freq1 = {}
    freq2 = {}
    unmap1 = {}
    unmap2 = {}
 
    # If the strings are of different lengths, they can't be converted
    if len(s1) != len(s2):
        return False
 
    # Calculate the frequency of each character in s1
    for char in s1:
        freq1[char] = freq1.get(char, 0) + 1
 
    # Calculate the frequency of each character in s2
    for char in s2:
        freq2[char] = freq2.get(char, 0) + 1
 
    # Count the frequency of each frequency in s2
    for value in freq2.values():
        unmap2[value] = unmap2.get(value, 0) + 1
 
    # Count the frequency of each frequency in s1
    for value in freq1.values():
        unmap1[value] = unmap1.get(value, 0) + 1
 
    # Check if every character in s1 is also in s2
    for char in s1:
        if char not in s2:
            return False
 
    # Check if every character in s2 is also in s1
    for char in s2:
        if char not in s1:
            return False
 
    # Check if the frequency of each frequency is the same in both strings
    for key, value in unmap1.items():
        if unmap2.get(key, 0) != value:
            return False
 
    # If all checks pass, the strings are converted
    return True
 
if __name__ == "__main__":
    s1 = "cabbba"
    s2 = "abbccc"
 
    # Print whether the strings are converted
    print("True" if canConvert(s1, s2) else "False")
 
 
# This code is contributed by Tapesh(tapeshdu420)


Output

True

Time Complexity: O(max(m + n)), where m and n are the size of s1 and s2 respectively.
Auxiliary Space: O(m + n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads