同构字符串

标签: 哈希表 字符串

难度: Easy

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

示例 1:

输入:s = "egg", t = "add"
输出:true

示例 2:

输入:s = "foo", t = "bar"
输出:false

示例 3:

输入:s = "paper", t = "title"
输出:true

提示:

  • 1 <= s.length <= 5 * 104
  • t.length == s.length
  • s 和 t 由任意有效的 ASCII 字符组成

Submission

运行时间: 20 ms

内存: 16.1 MB

class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        s2t, t2s = {}, {}
        for a, b in zip(s, t):
            # 对于已有映射 a -> s2t[a],若和当前字符映射 a -> b 不匹配,
            # 说明有一对多的映射关系,则返回 false ;
            # 对于映射 b -> a 也同理
            if a in s2t and s2t[a] != b or \
               b in t2s and t2s[b] != a:
                return False
            s2t[a], t2s[b] = b, a
        return True

# 作者:Krahets
# 链接:https://leetcode.cn/problems/isomorphic-strings/solutions/1645867/by-jyd-i4wt/
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Explain

该题解使用哈希表来解决同构字符串问题。具体思路如下: 1. 使用两个哈希表 s2t 和 t2s 分别存储字符串 s 到 t 的映射以及 t 到 s 的映射。 2. 遍历字符串 s 和 t,对于每个位置的字符 a 和 b: - 如果 a 已经存在于 s2t 中,且 s2t[a] 不等于 b,说明存在一对多的映射关系,返回 False。 - 如果 b 已经存在于 t2s 中,且 t2s[b] 不等于 a,说明存在多对一的映射关系,返回 False。 - 如果以上两种情况都不满足,将 a 映射到 b 存入 s2t,将 b 映射到 a 存入 t2s。 3. 遍历完成后,如果没有出现一对多或多对一的映射关系,则说明 s 和 t 是同构的,返回 True。

时间复杂度: O(n)

空间复杂度: O(n)

```python
class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        s2t, t2s = {}, {}  # 创建两个哈希表,分别存储 s 到 t 的映射和 t 到 s 的映射
        for a, b in zip(s, t):  # 同时遍历字符串 s 和 t
            # 对于已有映射 a -> s2t[a],若和当前字符映射 a -> b 不匹配,
            # 说明有一对多的映射关系,则返回 False;
            # 对于映射 b -> a 也同理
            if a in s2t and s2t[a] != b or \
               b in t2s and t2s[b] != a:
                return False
            s2t[a], t2s[b] = b, a  # 将 a 映射到 b 存入 s2t,将 b 映射到 a 存入 t2s
        return True  # 遍历完成后,如果没有出现一对多或多对一的映射关系,则返回 True
```

Explore

在同构字符串的问题中,要确保字符串 s 到 t 的映射是一一对应的,即每个字符 a 只能对应一个字符 b,同时每个字符 b 也只能对应一个字符 a。`s2t[a] != b`检查的是对于字符 a 的映射是否唯一;而`t2s[b] != a`检查的是对于字符 b 的映射是否唯一。这两者同时验证,可以确保不存在一对多或多对一的映射关系,从而验证字符串是否同构。

只使用一个哈希表不能有效解决问题,因为一个哈希表只能检查从一个方向的映射(例如只能从 s 到 t 的映射),这样只能保证没有一对多的映射,但不能保证没有多对一的映射。使用两个哈希表可以同时检查从 s 到 t 的映射和从 t 到 s 的映射,确保整个映射关系是一一对应的,从而完整地解决同构字符串的问题。

在处理大规模数据时,本方法的时间复杂度为 O(n),其中 n 是字符串的长度,这是因为需要遍历整个字符串来建立映射关系。空间复杂度也是 O(n),因为需要额外的空间来存储两个哈希表。这种方法在时间和空间效率上是较优的,但如果考虑到极端情况下的内存消耗,可能需要考虑更优化的空间使用策略。然而,在大多数情况下,这种一遍扫描的方法已经足够高效。

在 Python 中,哈希表(字典)的实现通常能有效地处理哈希碰撞,使得即使键的哈希值相同,键值对也能被正确存储和检索。因此,在本题中使用哈希表来存储字符映射时,即使发生哈希碰撞,也不会影响算法的正确性,因为字典会处理这些碰撞并保证每个键(字符)都正确映射到其对应的值(字符)。