Swift - LeetCode - 同构字符串

·  阅读 638

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情 

题目

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

如果 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|) 的空间。

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改