79
79
80
80
<!-- solution:start -->
81
81
82
- ### 方法一
82
+ ### 方法一:并查集
83
+
84
+ 我们可以使用并查集来处理等价字符的关系。每个字符可以看作一个节点,等价关系可以看作是连接这些节点的边。通过并查集,我们可以将所有等价的字符归为一类,并且在查询时能够快速找到每个字符的代表元素。我们在进行合并操作时,始终将代表元素设置为字典序最小的字符,这样可以确保最终得到的字符串是按字典序排列的最小等价字符串。
85
+
86
+ 时间复杂度 $O((n + m) \times \log |\Sigma|)$,空间复杂度 $O(|\Sigma|)$。其中 $n$ 是字符串 $s1$ 和 $s2$ 的长度,而 $m$ 是字符串 $baseStr$ 的长度,而 $|\Sigma|$ 是字符集的大小,本题中 $|\Sigma| = 26$。
83
87
84
88
<!-- tabs:start -->
85
89
@@ -88,54 +92,47 @@ tags:
88
92
``` python
89
93
class Solution :
90
94
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 :
94
96
if p[x] != x:
95
97
p[x] = find(p[x])
96
98
return p[x]
97
99
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
103
106
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)
111
109
```
112
110
113
111
#### Java
114
112
115
113
``` java
116
114
class Solution {
117
- private int [] p;
115
+ private final int [] p = new int [ 26 ] ;
118
116
119
117
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) {
122
119
p[i] = i;
123
120
}
124
121
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;
129
127
} else {
130
- p[pa ] = pb ;
128
+ p[px ] = py ;
131
129
}
132
130
}
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' ));
137
134
}
138
- return sb . toString( );
135
+ return String . valueOf(s );
139
136
}
140
137
141
138
private int find (int x ) {
@@ -152,68 +149,103 @@ class Solution {
152
149
``` cpp
153
150
class Solution {
154
151
public:
155
- vector<int > p;
156
-
157
152
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
+ }
168
170
}
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'));
173
174
}
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;
181
176
}
182
177
};
183
178
```
184
179
185
180
#### Go
186
181
187
182
```go
188
- var p []int
189
-
190
183
func smallestEquivalentString(s1 string, s2 string, baseStr string) string {
191
- p = make ([]int , 26 )
184
+ p : = make([]int, 26)
192
185
for i := 0; i < 26; i++ {
193
186
p[i] = i
194
187
}
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
+
195
197
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
200
204
} else {
201
- p[pa ] = pb
205
+ p[px ] = py
202
206
}
203
207
}
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'))) )
208
212
}
209
- return string (res)
213
+
214
+ return string(s)
210
215
}
216
+ ```
211
217
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 (' ' );
217
249
}
218
250
```
219
251
0 commit comments