Given two strings s and t, determine if they are isomorphic.
Two strings s and t are isomorphic if the characters in s can be replaced to get t.
All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character, but a character may map to itself.
Example 1:
Input: s = "egg", t = "add"
Output: true
Explanation:
The strings s and t can be made identical by:
'e' to 'a'.'g' to 'd'.Example 2:
Input: s = "foo", t = "bar"
Output: false
Explanation:
The strings s and t can not be made identical as 'o' needs to be mapped to both 'a' and 'r'.
Example 3:
Input: s = "paper", t = "title"
Output: true
Constraints:
1 <= s.length <= 5 * 104t.length == s.lengths and t consist of any valid ascii character.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute-force method for checking if two words are isomorphic is like trying every possible way to match the letters in the first word to letters in the second word. We explore all combinations and see if any of them work perfectly without breaking the rules of isomorphism.
Here's how the algorithm would work step-by-step:
def is_isomorphic_brute_force(first_word, second_word):
if len(first_word) != len(second_word):
return False
def find_isomorphism(index, mapping):
if index == len(first_word):
return True
first_word_character = first_word[index]
for second_word_character in set(second_word):
# Attempt to extend the current mapping with the new character
new_mapping = mapping.copy()
# Check if first character is already mapped to different second character
if first_word_character in new_mapping and new_mapping[first_word_character] != second_word_character:
continue
# Ensures no two characters map to the same character
if first_word_character not in new_mapping and second_word_character in new_mapping.values():
continue
new_mapping[first_word_character] = second_word_character
is_valid = True
for i in range(index + 1):
if first_word[i] in new_mapping:
if new_mapping[first_word[i]] != second_word[second_word.index(second_word_character)] and first_word[i] == first_word_character:
is_valid = False
break
elif first_word[i] == first_word_character:
is_valid = False
break
if is_valid:
consistent = True
for i in range(index):
if first_word[i] in new_mapping:
if first_word[index] in new_mapping and new_mapping[first_word[i]] == new_mapping[first_word[index]] and first_word[i] != first_word[index]:
consistent = False
break
if consistent:
# Recursively try to map the next character
if find_isomorphism(index + 1, new_mapping):
return True
return False
# Start with an empty mapping.
return find_isomorphism(0, {})The trick here is to check if a pattern between two strings is consistent. We can do this by tracking the relationships between characters in each string. If the relationships are not consistently one-to-one, the strings are not isomorphic.
Here's how the algorithm would work step-by-step:
def are_strings_isomorphic(string_one, string_two):
string_one_to_string_two_map = {}
string_two_to_string_one_map = {}
if len(string_one) != len(string_two):
return False
for i in range(len(string_one)):
character_one = string_one[i]
character_two = string_two[i]
# Check mapping from string_one to string_two
if character_one not in string_one_to_string_two_map:
# Ensure no existing mapping conflicts
if character_two in string_two_to_string_one_map:
return False
string_one_to_string_two_map[character_one] = character_two
string_two_to_string_one_map[character_two] = character_one
else:
# Verify existing mapping consistency
if string_one_to_string_two_map[character_one] != character_two:
return False
return True| Case | How to Handle |
|---|---|
| Both input strings are null | Return true, as null strings can be considered isomorphic to each other. |
| One string is null, the other is not | Return false, as strings of different 'lengths' (null vs. non-null) cannot be isomorphic. |
| Both strings are empty | Return true, as empty strings are isomorphic. |
| Strings have different lengths | Return false immediately, as strings of different lengths cannot be isomorphic. |
| Strings have length 1 | Return true, as single-character strings are always isomorphic to each other. |
| String s has repeating characters mapped to the same character in t | The mapping should maintain consistency; if a character in 's' maps to a character in 't', any other occurrence of that character in 's' should map to the same character in 't'. |
| String t has repeating characters that map to the same character in s | The reverse mapping should also maintain consistency; if a character in 't' maps to a character in 's', any other occurrence of that character in 't' should map to the same character in 's'. |
| Maximum string length with limited memory | The solution should be efficient in terms of memory usage as the strings can be very large, preventing stack overflow or exceeding memory limits by utilizing hash maps which have O(n) space complexity. |