This problem asks whether we can transform string str1
into string str2
using a specific type of conversion: converting all occurrences of a character in str1
to another lowercase English character.
Approach:
The solution employs a hash table (or dictionary in Python) to track the character mappings during the transformation. The core idea is to check for conflicts: if a character in str1
is already mapped to a different character, the transformation is impossible. A secondary check verifies that if str2
uses all 26 lowercase letters, no transformation is possible because there's no way to map any remaining characters in str1
without conflict.
Algorithm:
Handle Identical Strings: If str1
and str2
are identical, the transformation is trivially possible. Return true
.
Check for All Characters in str2: Create a set (or use a frequency count) to check if str2
contains all 26 lowercase English letters. If so, it's impossible to transform str1
to str2
because there would be no character left to map to. Return false
.
Character Mapping: Iterate through str1
and str2
simultaneously.
c
in str1
, check if it's already in the mapping (hash table d
).c
is not in d
, add a mapping from c
to the corresponding character in str2
.c
is in d
, check if its mapped character matches the corresponding character in str2
. If not, there's a conflict, and the transformation is impossible. Return false
.Success: If the loop completes without conflicts, the transformation is possible. Return true
.
Time Complexity: O(n), where n is the length of the strings. We iterate through the strings once.
Space Complexity: O(1) in the worst case. The hash table (or equivalent data structure) stores at most 26 character mappings (one for each lowercase letter). This is constant space, independent of the input string lengths.
Code Examples (with explanations):
The code examples in Python, Java, C++, Go, and TypeScript all follow the algorithm described above. The key differences lie in syntax and the specific data structures used (dictionaries/maps/arrays).
Python3:
class Solution:
def canConvert(self, str1: str, str2: str) -> bool:
if str1 == str2: #Identical strings: Trivial case
return True
if len(set(str2)) == 26: #str2 uses all 26 characters, impossible to map
return False
mapping = {}
for i in range(len(str1)):
char1, char2 = str1[i], str2[i]
if char1 not in mapping:
mapping[char1] = char2
elif mapping[char1] != char2: #Conflict: Already mapped to a different character
return False
return True
Java:
class Solution {
public boolean canConvert(String str1, String str2) {
if (str1.equals(str2)) return true;
Set<Character> set = new HashSet<>();
for (char c : str2.toCharArray()) set.add(c);
if (set.size() == 26) return false;
Map<Character, Character> map = new HashMap<>();
for (int i = 0; i < str1.length(); i++) {
char c1 = str1.charAt(i), c2 = str2.charAt(i);
if (!map.containsKey(c1)) map.put(c1, c2);
else if (map.get(c1) != c2) return false;
}
return true;
}
}
The other language examples (C++, Go, TypeScript) implement similar logic, adapting the syntax and data structures according to the language specifics. They all achieve the same time and space complexity.