7979
8080<!-- solution:start -->
8181
82- ### 方法一
82+ ### 方法一:并查集
83+
84+ 我们可以使用并查集来处理等价字符的关系。每个字符可以看作一个节点,等价关系可以看作是连接这些节点的边。通过并查集,我们可以将所有等价的字符归为一类,并且在查询时能够快速找到每个字符的代表元素。我们在进行合并操作时,始终将代表元素设置为字典序最小的字符,这样可以确保最终得到的字符串是按字典序排列的最小等价字符串。
85+
86+ 时间复杂度 $O((n + m) \times \log |\Sigma|)$,空间复杂度 $O(|\Sigma|)$。其中 $n$ 是字符串 $s1$ 和 $s2$ 的长度,而 $m$ 是字符串 $baseStr$ 的长度,而 $|\Sigma|$ 是字符集的大小,本题中 $|\Sigma| = 26$。
8387
8488<!-- tabs:start -->
8589
@@ -88,54 +92,47 @@ tags:
8892``` python
8993class Solution :
9094 def smallestEquivalentString (self , s1 : str , s2 : str , baseStr : str ) -> str :
91- p = list (range (26 ))
92-
93- def find (x ):
95+ def find (x : int ) -> int :
9496 if p[x] != x:
9597 p[x] = find(p[x])
9698 return p[x]
9799
98- for i in range (len (s1)):
99- a, b = ord (s1[i]) - ord (' a' ), ord (s2[i]) - ord (' a' )
100- pa, pb = find(a), find(b)
101- if pa < pb:
102- p[pb] = pa
100+ p = list (range (26 ))
101+ for a, b in zip (s1, s2):
102+ x, y = ord (a) - ord (" a" ), ord (b) - ord (" a" )
103+ px, py = find(x), find(y)
104+ if px < py:
105+ p[py] = px
103106 else :
104- p[pa] = pb
105-
106- res = []
107- for a in baseStr:
108- a = ord (a) - ord (' a' )
109- res.append(chr (find(a) + ord (' a' )))
110- return ' ' .join(res)
107+ p[px] = py
108+ return " " .join(chr (find(ord (c) - ord (" a" )) + ord (" a" )) for c in baseStr)
111109```
112110
113111#### Java
114112
115113``` java
116114class Solution {
117- private int [] p;
115+ private final int [] p = new int [ 26 ] ;
118116
119117 public String smallestEquivalentString (String s1 , String s2 , String baseStr ) {
120- p = new int [26 ];
121- for (int i = 0 ; i < 26 ; ++ i) {
118+ for (int i = 0 ; i < p. length; ++ i) {
122119 p[i] = i;
123120 }
124121 for (int i = 0 ; i < s1. length(); ++ i) {
125- int a = s1. charAt(i) - ' a' , b = s2. charAt(i) - ' a' ;
126- int pa = find(a), pb = find(b);
127- if (pa < pb) {
128- p[pb] = pa;
122+ int x = s1. charAt(i) - ' a' ;
123+ int y = s2. charAt(i) - ' a' ;
124+ int px = find(x), py = find(y);
125+ if (px < py) {
126+ p[py] = px;
129127 } else {
130- p[pa ] = pb ;
128+ p[px ] = py ;
131129 }
132130 }
133- StringBuilder sb = new StringBuilder ();
134- for (char a : baseStr. toCharArray()) {
135- char b = (char ) (find(a - ' a' ) + ' a' );
136- sb. append(b);
131+ char [] s = baseStr. toCharArray();
132+ for (int i = 0 ; i < s. length; ++ i) {
133+ s[i] = (char ) (' a' + find(s[i] - ' a' ));
137134 }
138- return sb . toString( );
135+ return String . valueOf(s );
139136 }
140137
141138 private int find (int x ) {
@@ -152,68 +149,103 @@ class Solution {
152149``` cpp
153150class Solution {
154151public:
155- vector<int > p;
156-
157152 string smallestEquivalentString(string s1, string s2, string baseStr) {
158- p.resize(26);
159- for (int i = 0; i < 26; ++i)
160- p[i] = i;
161- for (int i = 0; i < s1.size(); ++i) {
162- int a = s1[i] - 'a', b = s2[i] - 'a';
163- int pa = find(a), pb = find(b);
164- if (pa < pb)
165- p[pb] = pa;
166- else
167- p[pa] = pb;
153+ vector<int > p(26);
154+ iota(p.begin(), p.end(), 0);
155+ auto find = [ &] (this auto&& find, int x) -> int {
156+ if (p[ x] != x) {
157+ p[ x] = find(p[ x] );
158+ }
159+ return p[ x] ;
160+ };
161+ for (int i = 0; i < s1.length(); ++i) {
162+ int x = s1[ i] - 'a';
163+ int y = s2[ i] - 'a';
164+ int px = find(x), py = find(y);
165+ if (px < py) {
166+ p[ py] = px;
167+ } else {
168+ p[ px] = py;
169+ }
168170 }
169- string res = " " ;
170- for (char a : baseStr) {
171- char b = (char) (find(a - 'a') + 'a');
172- res += b;
171+ string s;
172+ for (char c : baseStr) {
173+ s.push_back('a' + find(c - 'a'));
173174 }
174- return res;
175- }
176-
177- int find(int x) {
178- if (p[x] != x)
179- p[x] = find(p[x]);
180- return p[x];
175+ return s;
181176 }
182177};
183178```
184179
185180#### Go
186181
187182```go
188- var p []int
189-
190183func smallestEquivalentString(s1 string, s2 string, baseStr string) string {
191- p = make ([]int , 26 )
184+ p : = make([]int, 26)
192185 for i := 0; i < 26; i++ {
193186 p[i] = i
194187 }
188+
189+ var find func(int) int
190+ find = func(x int) int {
191+ if p[x] != x {
192+ p[x] = find(p[x])
193+ }
194+ return p[x]
195+ }
196+
195197 for i := 0; i < len(s1); i++ {
196- a , b := int (s1[i]-' a' ), int (s2[i]-' a' )
197- pa , pb := find (a), find (b)
198- if pa < pb {
199- p[pb] = pa
198+ x := int(s1[i] - 'a')
199+ y := int(s2[i] - 'a')
200+ px := find(x)
201+ py := find(y)
202+ if px < py {
203+ p[py] = px
200204 } else {
201- p[pa ] = pb
205+ p[px ] = py
202206 }
203207 }
204- var res [] byte
205- for _ , a := range baseStr {
206- b := byte ( find ( int (a- ' a ' ))) + ' a '
207- res = append (res, b )
208+
209+ var s []byte
210+ for i := 0; i < len(baseStr); i++ {
211+ s = append(s, byte('a'+find(int(baseStr[i]-'a'))) )
208212 }
209- return string (res)
213+
214+ return string(s)
210215}
216+ ```
211217
212- func find (x int ) int {
213- if p[x] != x {
214- p[x] = find (p[x])
215- }
216- return p[x]
218+ #### TypeScript
219+
220+ ``` ts
221+ function smallestEquivalentString(s1 : string , s2 : string , baseStr : string ): string {
222+ const p: number [] = Array .from ({ length: 26 }, (_ , i ) => i );
223+
224+ const find = (x : number ): number => {
225+ if (p [x ] !== x ) {
226+ p [x ] = find (p [x ]);
227+ }
228+ return p [x ];
229+ };
230+
231+ for (let i = 0 ; i < s1 .length ; i ++ ) {
232+ const x = s1 .charCodeAt (i ) - ' a' .charCodeAt (0 );
233+ const y = s2 .charCodeAt (i ) - ' a' .charCodeAt (0 );
234+ const px = find (x );
235+ const py = find (y );
236+ if (px < py ) {
237+ p [py ] = px ;
238+ } else {
239+ p [px ] = py ;
240+ }
241+ }
242+
243+ const s: string [] = [];
244+ for (let i = 0 ; i < baseStr .length ; i ++ ) {
245+ const c = baseStr .charCodeAt (i ) - ' a' .charCodeAt (0 );
246+ s .push (String .fromCharCode (' a' .charCodeAt (0 ) + find (c )));
247+ }
248+ return s .join (' ' );
217249}
218250```
219251
0 commit comments