Problem Statement
Given two strings s and t, determine if they are isomorphic.
Two strings are isomorphic if the characters in s can be replaced to get t. All occurrences of a character in s must map to the same character in t, and no two characters in s may map to the same character in t.
Function Signature:
go
func isIsomorphic(s string, t string) bool
Example 1:
go
fmt.Println(isIsomorphic("egg", "add")) // Output: true
Explanation: The characters 'e' and 'g' map to 'a' and 'd', respectively.
Example 2:
go
fmt.Println(isIsomorphic("foo", "bar")) // Output: false
Explanation: The characters 'f' and 'o' in s map to 'b' and 'a' in t, but the second 'o' in s maps to both 'a' and 'r', which is not allowed.
Example 3:
go
fmt.Println(isIsomorphic("paper", "title")) // Output: true
Explanation: The characters 'p', 'a', 'e', and 'r' map to 't', 'i', 'l', and 'e', respectively.
Constraints:
1 <= s.length, t.length <= 5 * 10^4
s and t consist of any printable ASCII character.
Approach
To solve this problem, we need to check if each character in s can be mapped to a unique character in t, and vice versa. This means two mappings need to be valid:
- Mapping from
s to t: Each character in s must map to one unique character in t.
- Mapping from
t to s: Each character in t must map to one unique character in s.
To achieve this:
- We can use two hash maps (or dictionaries) to keep track of the character mappings.
- One hash map will store the mapping from
s to t, and another hash map will store the mapping from t to s.
Steps:
- Iterate through the characters of both strings
s and t simultaneously.
- For each character pair
(s[i], t[i]), check if the character in s already has a mapping to a different character in t and vice versa.
- If any mapping conflict occurs, return
false.
- If all characters are mapped correctly, return
true.
Time Complexity:
- O(n), where
n is the length of the strings. We make a single pass through the strings.
Go Implementation
go
package main
import "fmt"
// Function to check if two strings are isomorphic
func isIsomorphic(s string, t string) bool {
if len(s) != len(t) {
return false
}
// Two maps to store the character mappings
sToT := make(map[byte]byte)
tToS := make(map[byte]byte)
// Iterate through the characters of both strings
for i := 0; i < len(s); i++ {
if sToT[s[i]] != 0 && sToT[s[i]] != t[i] {
return false
}
if tToS[t[i]] != 0 && tToS[t[i]] != s[i] {
return false
}
sToT[s[i]] = t[i]
tToS[t[i]] = s[i]
}
return true
}
func main() {
// Example 1
fmt.Println(isIsomorphic("egg", "add")) // Output: true
// Example 2
fmt.Println(isIsomorphic("foo", "bar")) // Output: false
// Example 3
fmt.Println(isIsomorphic("paper", "title")) // Output: true
}
Explanation of the Code:
1. isIsomorphic Function:
- Input: The function takes two strings
s and t.
- Edge Case Check: If the lengths of
s and t are not equal, they cannot be isomorphic, so we return false.
- Mapping Initialization: We create two maps (
sToT and tToS) to store the mappings from characters in s to t and from t to s, respectively.
- Iteration and Mapping Validation:
- For each character pair
(s[i], t[i]), we check if the current character in s is already mapped to a different character in t or vice versa.
- If a conflict occurs, we return
false. Otherwise, we update the mappings.
- Return True: If we complete the iteration without conflicts, we return
true.
2. Main Function:
- The
main function tests the isIsomorphic function with a few sample test cases.
Example Walkthrough
Example 1:
Input:
go
fmt.Println(isIsomorphic("egg", "add"))
- The mapping for
s = "egg" and t = "add" is:
'e' maps to 'a'
'g' maps to 'd'
- All characters are mapped correctly, so the function should return
true.
Output: true
Example 2:
Input:
go
fmt.Println(isIsomorphic("foo", "bar"))
- The mapping for
s = "foo" and t = "bar" is:
'f' maps to 'b'
'o' maps to 'a'
- The second
'o' in s would map to both 'a' and 'r', causing a conflict.
- The function should return
false.
Output: false
Example 3:
Input:
go
fmt.Println(isIsomorphic("paper", "title"))
- The mapping for
s = "paper" and t = "title" is:
'p' maps to 't'
'a' maps to 'i'
'e' maps to 'l'
'r' maps to 'e'
- All characters are mapped correctly, so the function should return
true.
Output: true
Conclusion
The LeetCode 205: Isomorphic Strings problem is efficiently solved using two hash maps to track the character mappings between the strings. This solution ensures that we check both mappings from s to t and from t to s, ensuring a valid isomorphism.
This approach runs in O(n) time, where n is the length of the strings, which is optimal for this problem.