Given two strings str1 and str2 of the same length, the task is to determine if str1 can be transformed into str2 using the following operation as many times as needed:
str1 and change all its occurrences to any other lowercase English character.Constraints:
str1 to the same character in str2 in a single operation.str1 and str2 consist only of lowercase English letters and are of equal length.
The goal is to return True if it's possible to transform str1 into str2 using the allowed operations, or False otherwise.
At first glance, it seems like you can always convert str1 to str2 by repeatedly replacing characters. However, the key constraints are:
str1 to the same character in str2 unless you use an intermediate character.
The brute-force way would be to try all possible transformation sequences, but that's inefficient. Instead, we can analyze the mapping from characters in str1 to str2:
str1 would need to be mapped to more than one character in str2, transformation is impossible.This leads us to a more optimized solution using character mapping and checking for cycles.
We solve the problem step-by-step as follows:
str1 is already equal to str2, return True.i, map str1[i] to str2[i].str1 maps to different characters in str2 at different positions, return False.str2) uses all 26 lowercase letters, and the mapping is a permutation, then there is no "spare" character to use as a temporary placeholder, so transformation is impossible. Return False in this case.True.
We use a hash map (dictionary) for efficient lookups and to ensure each character in str1 maps to only one character in str2.
Let's use the example: str1 = "ab", str2 = "ba"
'a' in str1 maps to 'b' in str2.'b' in str1 maps to 'a' in str2.'a' and 'b' are used, but not all 26 letters are used. So, we can use an unused character (like 'c') as a temporary placeholder.'a' to 'c': "cb"'b' to 'a': "ca"'c' to 'b': "ba""ab" to "ba" using allowed operations.Brute-force approach:
n.The key insight is to model the transformation as a mapping of characters and to detect if a cycle prevents transformation due to lack of a spare character. By using a hash map to record mappings and a set to check for full alphabet usage, we can efficiently determine if the transformation is possible. This approach is both elegant and optimal, leveraging simple data structures and clear logic to solve the problem.
class Solution:
def canConvert(self, str1: str, str2: str) -> bool:
if str1 == str2:
return True
mapping = {}
for c1, c2 in zip(str1, str2):
if c1 in mapping:
if mapping[c1] != c2:
return False
else:
mapping[c1] = c2
# If all 26 characters are used as targets, no spare character for swap
return len(set(str2)) < 26
class Solution {
public:
bool canConvert(string str1, string str2) {
if (str1 == str2) return true;
unordered_map<char, char> mapping;
for (int i = 0; i < str1.size(); ++i) {
if (mapping.count(str1[i])) {
if (mapping[str1[i]] != str2[i]) return false;
} else {
mapping[str1[i]] = str2[i];
}
}
unordered_set<char> targets(str2.begin(), str2.end());
return targets.size() < 26;
}
};
class Solution {
public boolean canConvert(String str1, String str2) {
if (str1.equals(str2)) return true;
Map<Character, Character> mapping = new HashMap<>();
for (int i = 0; i < str1.length(); i++) {
char c1 = str1.charAt(i), c2 = str2.charAt(i);
if (mapping.containsKey(c1)) {
if (mapping.get(c1) != c2) return false;
} else {
mapping.put(c1, c2);
}
}
Set<Character> targets = new HashSet<>();
for (char c : str2.toCharArray()) targets.add(c);
return targets.size() < 26;
}
}
var canConvert = function(str1, str2) {
if (str1 === str2) return true;
let mapping = {};
for (let i = 0; i < str1.length; i++) {
let c1 = str1[i], c2 = str2[i];
if (c1 in mapping) {
if (mapping[c1] !== c2) return false;
} else {
mapping[c1] = c2;
}
}
let targets = new Set(str2);
return targets.size < 26;
};