【LeetCode】205. 同构字符串

leetcode

 

问题分析

判断两个字符串是否为同构字符串需满足以下条件:

  1. 一一映射s 中的每个字符必须唯一映射到 t 中的一个字符,反之亦然。
  2. 顺序保留:字符替换后顺序与原字符串一致。
  3. 双向检查:需确保 s→t 和 t→s 的映射关系均不冲突。

Golang实现思路

基于搜索结果中的 ​双向哈希表映射法,具体步骤如下:

  1. 初始化映射表:创建两个字典 sMap 和 tMap,分别记录 s→t 和 t→s 的字符映射关系。
  2. 遍历字符对:逐个比较 s 和 t 的对应字符。
  3. 双向检查映射
    • 若 s[i] 已存在于 sMap 中,检查其映射值是否等于 t[i]
    • 若 t[i] 已存在于 tMap 中,检查其映射值是否等于 s[i]
  4. 更新映射表:若映射关系合法且未被记录,则将字符对添加到映射表中。
  5. 返回结果:若遍历中未发现冲突,则字符串同构。

Golang实现代码

func isIsomorphic(s string, t string) bool {
    if len(s) != len(t) { // 长度不同直接返回false
        return false
    }

    sMap := make(map[byte]byte) // 记录s→t的映射
    tMap := make(map[byte]byte) // 记录t→s的映射

    for i := 0; i < len(s); i++ {
        sChar := s[i]
        tChar := t[i]

        // 检查s→t的映射是否冲突
        if mappedTChar, exists := sMap[sChar]; exists {
            if mappedTChar != tChar {
                return false
            }
        } else {
            // 检查t→s的映射是否冲突
            if mappedSChar, exists := tMap[tChar]; exists {
                if mappedSChar != sChar {
                    return false
                }
            }
            // 更新双向映射
            sMap[sChar] = tChar
            tMap[tChar] = sChar
        }
    }
    return true
}

 


代码解释与关键点

  1. 长度检查​(第2行):若两字符串长度不同,直接返回 false。
  2. 双向映射表​(第5-6行):通过两个字典确保映射关系的唯一性,防止 s="ab"t="aa" 这类单向映射合法的错误情况。
  3. 冲突检查逻辑​(第10-20行):
    • 若 sChar 已映射到其他字符,或 tChar 已被其他字符映射,则返回 false
    • 仅当双向映射均未记录时,才更新映射表,避免重复映射。

测试用例验证

func main() {
    fmt.Println(isIsomorphic("egg", "add"))   // true(e→a, g→d)
    fmt.Println(isIsomorphic("foo", "bar"))   // false(o无法同时映射到a和r)
    fmt.Println(isIsomorphic("paper", "title")) // true(p→t, a→i, e→l, r→e)
    fmt.Println(isIsomorphic("ab", "aa"))     // false(b→a与a→a冲突)
}

 


复杂度分析

维度说明
时间复杂度 O(n),遍历字符串一次完成所有检查。
空间复杂度 O(n),最坏情况下存储所有字符的映射关系。

扩展优化

  1. 数组替代哈希表:若字符仅限ASCII码(0-255),可用长度为256的数组代替字典,提升性能。
  2. 索引比较法:通过比较字符首次出现的位置是否一致,但需注意字符串遍历效率。
posted @ 2025-03-19 20:18  云隙之间  阅读(31)  评论(0)    收藏  举报