携手创造,一起成长!这是我参与「日新计划 8 月更文应战」的第13天,点击查看活动概况

题目

给定两个字符串st,判别它们是否是同构的。

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

每个呈现的字符都应当映射到另一个字符,一起不改动字符的次序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符能够映射到自己本身。

示例 1:

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

示例 2:

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

示例 3:

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

办法一:哈希

思路及解法

此题是「290. 单词规律」的简化版,需求咱们判别 st 每个方位上的字符是否都一一对应,即 s 的恣意一个字符被 t 中仅有的字符对应,一起 t 的恣意一个字符被 s 中仅有的字符对应。这也被称为「双射」的联系。

以示例 22 为例,t 中的字符 ar 虽然有仅有的映射 o,但对于 s 中的字符 o 来说其存在两个映射 {a,r}\{a,r\},故不满足条件。

因而,咱们保护两张哈希表,第一张哈希表 s2t\textit{s2t}s 中字符为键,映射至 t 的字符为值,第二张哈希表 t2s\textit{t2s}t 中字符为键,映射至 s 的字符为值。从左至右遍历两个字符串的字符,不断更新两张哈希表,如果呈现抵触(即当时下标 index\textit{index} 对应的字符 s[index]s[\textit{index}] 现已存在映射且不为 t[index]t[\textit{index}] 或当时下标 index\textit{index} 对应的字符 t[index]t[\textit{index}] 现已存在映射且不为 s[index]s[\textit{index}])时阐明两个字符串无法构成同构,回来 false\rm false

如果遍历结束没有呈现抵触,则标明两个字符串是同构的,回来 true\rm true 即可。

代码

class Solution {
    func isIsomorphic(_ s: String, _ t: String) -> Bool {
        let s = Array(s)
        let t = Array(t)
        var s2t: [Character:Character] = [Character:Character]()
        var t2s: [Character:Character] = [Character:Character]()
        for i in 0..<s.count {
            let x: Character = s[i]
            let y: Character = t[i]
            if (nil != s2t[x] && s2t[x] != y) || (nil != t2s[y] && t2s[y] != x) {
                return false
            }
            s2t[x] = y
            t2s[y] = x
        }
        return true
    }
}

复杂度分析

  • 时刻复杂度:O(n)O(n),其间 nn 为字符串的长度。咱们只需一起遍历一遍字符串 sstt 即可。

  • 空间复杂度:O(∣∣)O(∣∣),其间 \Sigma 是字符串的字符集。哈希表存储字符的空间取决于字符串的字符集大小,最坏情况下每个字符均不相同,需求 O(∣∣)O(|\Sigma|) 的空间。