原题说明
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 inAandB, 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 inAandB, we can group their characters as[h,w],[d,e,o],[l,r]. So only the second letter‘o’inSis changed to‘d’, the answer is“hdld”.
Example 3:
Input: A = “leetcode”, B = “programs”, S = “sourcecode”
Output: “aauaaaaada”
Explanation: We group the equivalent characters inAandBas[a,o,e,r,s,c],[l,p],[g,t]and[d,m], thus all letters inSexcept‘u’and‘d’are transformed to‘a’, the answer is“aauaaaaada”.
Note:
- String
A,BandSconsist of only lowercase English letters from‘a’-‘z’. - The lengths of string
A,BandSare between1and1000. - String
AandBare 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上更新了视频讲解,欢迎关注!