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:
#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;
}
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");
}
}
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");
}
}
// 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();
# 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)