原题说明
Given strings A
and B
of the same length, we say A[i] and B[i] are equivalent characters. For example, if A = “abc”
and B = “cde”
, then we have ‘a’ == ‘c’, ‘b’ == ‘d’, ‘c’ == ‘e’
.
Equivalent characters follow the usual rules of any equivalence relation:
- Reflexivity: ‘a’ == ‘a’
- Symmetry: ‘a’ == ‘b’ implies ‘b’ == ‘a’
- Transitivity: ‘a’ == ‘b’ and ‘b’ == ‘c’ implies ‘a’ == ‘c’
For example, given the equivalency information from A
and B
above, S = “eed”
, “acd”
, and “aab”
are equivalent strings, and “aab”
is the lexicographically smallest equivalent string of S
.
Return the lexicographically smallest equivalent string of S
by using the equivalency information from A
and B
.
Example 1:
Input: A = “parker”, B = “morris”, S = “parser”
Output: “makkek”
Explanation: Based on the equivalency information inA
andB
, we can group their characters as[m,p]
,[a,o]
,[k,r,s]
,[e,i]
. The characters in each group are equivalent and sorted in lexicographical order. So the answer is“makkek”
.
Example 2:
Input: A = “hello”, B = “world”, S = “hold”
Output: “hdld”
Explanation: Based on the equivalency information inA
andB
, we can group their characters as[h,w]
,[d,e,o]
,[l,r]
. So only the second letter‘o’
inS
is changed to‘d’
, the answer is“hdld”
.
Example 3:
Input: A = “leetcode”, B = “programs”, S = “sourcecode”
Output: “aauaaaaada”
Explanation: We group the equivalent characters inA
andB
as[a,o,e,r,s,c]
,[l,p]
,[g,t]
and[d,m]
, thus all letters inS
except‘u’
and‘d’
are transformed to‘a’
, the answer is“aauaaaaada”
.
Note:
- String
A
,B
andS
consist of only lowercase English letters from‘a’
-‘z’
. - The lengths of string
A
,B
andS
are between1
and1000
. - String
A
andB
are of the same length.
解题思路
这道题很多网上解答是用了Union find,实际上并不是最好的方法。
Union find比较适合union与find操作交错的情况,比如Number of Islands II.
但是这里的话,如果使用Union find,需要先进行一系列union操作,然后进行一系列find操作,时间复杂度是O((M + N)log*(M))
,近似于O(M + N)
. 但是实际上直接使用DFS或者BFS遍历,也可以达到O(M + N)
的时间复杂度:
- 首先遍历
A
和B
,创建一个字母间关联的无向图mapping
- 遍历
S
,对于S
中的每一个字母s
,在无向图中进行一次DFS(BFS也可以),找寻关联字母中最小的字母,同时用一个unordered_set visited
记录遍历到的点。 visited
中的点都是与当前字母s
关联的,因此对应的最小字母是一样的,用一个unordered_map memo
来记录visited
中的点与最小字母的对应关系,这样下次遍历到这些点,就不用再做dfs了,直接从memo
中查到对应的最小字母即可。
假设A
和B
的长度是M
,S
的长度是N
,由于mapping
中每一个字母(节点)和每一条边遍历了一遍,这是一个O(M)
的时间复杂度,创建mapping
是O(M)
的时间复杂度,遍历S
的时间复杂度为O(N)
所以总的时间复杂度是O(2M + N)
也是近似于O(M + N)
示例代码 (cpp)
1 | class Solution { |
示例代码 (java)
1 | // Union Find |
示例代码 (python)
1 | class Solution: |
复杂度分析
时间复杂度: O(M + N)
, 假设A
和B
的长度是M
,S
的长度是N
空间复杂度: O(M)
, 即mapping
占用的空间
视频讲解
我们在Youtube上更新了视频讲解,欢迎关注!