在问 · 算法题解

205. 同构字符串

题目描述

输入两个长度相同的字符串 s 和 t。判断能否把 s 中的字符逐个替换,得到 t。能则称两者同构,返回 true,否则返回 false。

替换要遵守一套固定的对应规则:同一个字符每次都换成同一个字符;两个不同的字符不能换成同一个字符;字符可以对应它自己。替换不改变字符的位置。

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

解释:令 'e' 对应 'a'、'g' 对应 'd' 即可。

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

解释:'o' 在 t 中需要同时对应 'a' 和 'r',不可能。

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

解释:p→t、a→i、e→l、r→e 是一套合法的对应关系。

数据范围

  • 1 <= s.length <= 5 * 10^4
  • t.length == s.length
  • s 和 t 由合法的 ASCII 字符组成。

解题思路

同构要求映射是双射,所以用两张表:st 记录 s 的字符映射到 t 的哪个字符,ts 记录反方向。逐对扫描 (a, b):如果 st 里 a 已经映射到别的字符,或者 ts 里 b 已经被别的字符占用,就冲突返回 false;否则记下这对映射。

为什么正确

处理完前 i 对字符后,st 和 ts 互为逆映射,且前缀 s[:i] 经 st 替换后恰好等于 t[:i]。

复杂度分析

时间 O(n);空间 O(|Σ|),Σ 为字符集。

易错点

只用一张 s→t 的表不够:s="ab", t="aa" 时 a→a、b→a 各自不冲突,但两个字符映射到了同一个字符,必须用反向表 ts 拦住。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        st, ts = {}, {}
        for a, b in zip(s, t):
            if st.get(a, b) != b or ts.get(b, a) != a:
                return False
            st[a] = b
            ts[b] = a
        return True

载入编辑器,自己跑一遍 →

字符串 专题的其他题目

查看 字符串 全部题目 →