题目
给定两个字符串 s
和 t
,判断它们是否是同构的。
如果 s
中的字符可以按某种映射关系替换得到 t
,那么这两个字符串是同构的。
每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。
示例 1:
- 输入:
s = "egg", t = "add"
- 输出:
true
示例 2:
- 输入:
s = "foo", t = "bar"
- 输出:
false
示例 3:
- 输入:
s = "paper", t = "title"
- 输出:
true
方法一:哈希表
思路及解法
此题是「290. 单词规律」的简化版,需要我们判断 s
和 t
每个位置上的字符是否都一一对应,即 s
的任意一个字符被 t
中唯一的字符对应,同时 t
的任意一个字符被 s
中唯一的字符对应。这也被称为「双射」的关系。
以示例 22 为例,t
中的字符 a
和 r
虽然有唯一的映射 o
,但对于 s
中的字符 o
来说其存在两个映射 ,故不满足条件。
因此,我们维护两张哈希表,第一张哈希表 以 s
中字符为键,映射至 t
的字符为值,第二张哈希表 以 t
中字符为键,映射至 s
的字符为值。从左至右遍历两个字符串的字符,不断更新两张哈希表,如果出现冲突(即当前下标 对应的字符 已经存在映射且不为 或当前下标 对应的字符 已经存在映射且不为 )时说明两个字符串无法构成同构,返回 。
如果遍历结束没有出现冲突,则表明两个字符串是同构的,返回 即可。
代码
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
}
}
复杂度分析
-
时间复杂度:,其中 为字符串的长度。我们只需同时遍历一遍字符串 和 即可。
-
空间复杂度:,其中 是字符串的字符集。哈希表存储字符的空间取决于字符串的字符集大小,最坏情况下每个字符均不相同,需要 的空间。
网友评论