携手创造,一起成长!这是我参与「日新计划 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. 单词规律」的简化版,需求咱们判别 s
和 t
每个方位上的字符是否都一一对应,即 s
的恣意一个字符被 t
中仅有的字符对应,一起 t
的恣意一个字符被 s
中仅有的字符对应。这也被称为「双射」的联系。
以示例 22 为例,t
中的字符 a
和 r
虽然有仅有的映射 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 为字符串的长度。咱们只需一起遍历一遍字符串 ss 和 tt 即可。
-
空间复杂度:O(∣∣)O(∣∣),其间 \Sigma 是字符串的字符集。哈希表存储字符的空间取决于字符串的字符集大小,最坏情况下每个字符均不相同,需求 O(∣∣)O(|\Sigma|) 的空间。