@@ -59,28 +59,246 @@ a = 3, b = 1 和 c = 2.
59
59
60
60
<!-- 这里可写通用的实现逻辑 -->
61
61
62
+ ** 方法一:带权并查集**
63
+
64
+ 我们先将字符串转换成从 $0$ 开始的整数,然后遍历所有的等式,将等式中的两个字符串映射成对应的整数 $a$ 和 $b$,如果这两个整数不在同一个集合中,就将它们合并到同一个集合中,并且记录下两个整数的权值,即 $a$ 与 $b$ 的比值。如果这两个整数在同一个集合中,就判断它们的权值是否满足等式,如果不满足就返回 ` true ` 。
65
+
66
+ 时间复杂度 $O(n \times \log n)$ 或 $O(n \times \alpha(n))$,空间复杂度 $O(n)$。其中 $n$ 是等式的数量。
67
+
68
+ 相似题目:
69
+
70
+ - [ 399. 除法求值] ( /solution/0300-0399/0399.Evaluate%20Division/README.md )
71
+
62
72
<!-- tabs:start -->
63
73
64
74
### ** Python3**
65
75
66
76
<!-- 这里可写当前语言的特殊实现逻辑 -->
67
77
68
78
``` python
69
-
79
+ class Solution :
80
+ def checkContradictions (
81
+ self , equations : List[List[str ]], values : List[float ]
82
+ ) -> bool :
83
+ def find (x : int ) -> int :
84
+ if p[x] != x:
85
+ root = find(p[x])
86
+ w[x] *= w[p[x]]
87
+ p[x] = root
88
+ return p[x]
89
+
90
+ d = defaultdict(int )
91
+ n = 0
92
+ for e in equations:
93
+ for s in e:
94
+ if s not in d:
95
+ d[s] = n
96
+ n += 1
97
+ p = list (range (n))
98
+ w = [1.0 ] * n
99
+ eps = 1e-5
100
+ for (a, b), v in zip (equations, values):
101
+ a, b = d[a], d[b]
102
+ pa, pb = find(a), find(b)
103
+ if pa != pb:
104
+ p[pb] = pa
105
+ w[pb] = v * w[a] / w[b]
106
+ elif abs (v * w[a] - w[b]) >= eps:
107
+ return True
108
+ return False
70
109
```
71
110
72
111
### ** Java**
73
112
74
113
<!-- 这里可写当前语言的特殊实现逻辑 -->
75
114
76
115
``` java
116
+ class Solution {
117
+ private int [] p;
118
+ private double [] w;
119
+
120
+ public boolean checkContradictions (List<List<String > > equations , double [] values ) {
121
+ Map<String , Integer > d = new HashMap<> ();
122
+ int n = 0 ;
123
+ for (var e : equations) {
124
+ for (var s : e) {
125
+ if (! d. containsKey(s)) {
126
+ d. put(s, n++ );
127
+ }
128
+ }
129
+ }
130
+ p = new int [n];
131
+ w = new double [n];
132
+ for (int i = 0 ; i < n; ++ i) {
133
+ p[i] = i;
134
+ w[i] = 1.0 ;
135
+ }
136
+ final double eps = 1e-5 ;
137
+ for (int i = 0 ; i < equations. size(); ++ i) {
138
+ int a = d. get(equations. get(i). get(0 )), b = d. get(equations. get(i). get(1 ));
139
+ int pa = find(a), pb = find(b);
140
+ double v = values[i];
141
+ if (pa != pb) {
142
+ p[pb] = pa;
143
+ w[pb] = v * w[a] / w[b];
144
+ } else if (Math . abs(v * w[a] - w[b]) >= eps) {
145
+ return true ;
146
+ }
147
+ }
148
+ return false ;
149
+ }
150
+
151
+ private int find (int x ) {
152
+ if (p[x] != x) {
153
+ int root = find(p[x]);
154
+ w[x] *= w[p[x]];
155
+ p[x] = root;
156
+ }
157
+ return p[x];
158
+ }
159
+ }
160
+ ```
77
161
162
+ ### ** C++**
163
+
164
+ ``` cpp
165
+ class Solution {
166
+ public:
167
+ bool checkContradictions(vector<vector<string >>& equations, vector<double >& values) {
168
+ unordered_map<string, int> d;
169
+ int n = 0;
170
+ for (auto& e : equations) {
171
+ for (auto& s : e) {
172
+ if (!d.count(s)) {
173
+ d[ s] = n++;
174
+ }
175
+ }
176
+ }
177
+ vector<int > p(n);
178
+ iota(p.begin(), p.end(), 0);
179
+ vector<double > w(n, 1.0);
180
+ function<int(int)> find = [ &] (int x) -> int {
181
+ if (p[ x] != x) {
182
+ int root = find(p[ x] );
183
+ w[ x] * = w[ p[ x]] ;
184
+ p[ x] = root;
185
+ }
186
+ return p[ x] ;
187
+ };
188
+ for (int i = 0; i < equations.size(); ++i) {
189
+ int a = d[ equations[ i] [ 0 ]] , b = d[ equations[ i] [ 1 ]] ;
190
+ double v = values[ i] ;
191
+ int pa = find(a), pb = find(b);
192
+ if (pa != pb) {
193
+ p[ pb] = pa;
194
+ w[ pb] = v * w[ a] / w[ b] ;
195
+ } else if (fabs(v * w[ a] - w[ b] ) >= 1e-5) {
196
+ return true;
197
+ }
198
+ }
199
+ return false;
200
+ }
201
+ };
202
+ ```
203
+
204
+ ### **Go**
205
+
206
+ ```go
207
+ func checkContradictions(equations [][]string, values []float64) bool {
208
+ d := make(map[string]int)
209
+ n := 0
210
+
211
+ for _, e := range equations {
212
+ for _, s := range e {
213
+ if _, ok := d[s]; !ok {
214
+ d[s] = n
215
+ n++
216
+ }
217
+ }
218
+ }
219
+
220
+ p := make([]int, n)
221
+ for i := range p {
222
+ p[i] = i
223
+ }
224
+
225
+ w := make([]float64, n)
226
+ for i := range w {
227
+ w[i] = 1.0
228
+ }
229
+
230
+ var find func(int) int
231
+ find = func(x int) int {
232
+ if p[x] != x {
233
+ root := find(p[x])
234
+ w[x] *= w[p[x]]
235
+ p[x] = root
236
+ }
237
+ return p[x]
238
+ }
239
+ for i, e := range equations {
240
+ a, b := d[e[0]], d[e[1]]
241
+ v := values[i]
242
+
243
+ pa, pb := find(a), find(b)
244
+ if pa != pb {
245
+ p[pb] = pa
246
+ w[pb] = v * w[a] / w[b]
247
+ } else if v*w[a]-w[b] >= 1e-5 || w[b]-v*w[a] >= 1e-5 {
248
+ return true
249
+ }
250
+ }
251
+
252
+ return false
253
+ }
78
254
```
79
255
80
256
### ** TypeScript**
81
257
82
258
``` ts
83
-
259
+ function checkContradictions(equations : string [][], values : number []): boolean {
260
+ const d: { [key : string ]: number } = {};
261
+ let n = 0 ;
262
+
263
+ for (const e of equations ) {
264
+ for (const s of e ) {
265
+ if (! (s in d )) {
266
+ d [s ] = n ;
267
+ n ++ ;
268
+ }
269
+ }
270
+ }
271
+
272
+ const p: number [] = Array .from ({ length: n }, (_ , i ) => i );
273
+ const w: number [] = Array .from ({ length: n }, () => 1.0 );
274
+
275
+ const find = (x : number ): number => {
276
+ if (p [x ] !== x ) {
277
+ const root = find (p [x ]);
278
+ w [x ] *= w [p [x ]];
279
+ p [x ] = root ;
280
+ }
281
+ return p [x ];
282
+ };
283
+
284
+ for (let i = 0 ; i < equations .length ; i ++ ) {
285
+ const a = d [equations [i ][0 ]];
286
+ const b = d [equations [i ][1 ]];
287
+ const v = values [i ];
288
+
289
+ const pa = find (a );
290
+ const pb = find (b );
291
+
292
+ if (pa !== pb ) {
293
+ p [pb ] = pa ;
294
+ w [pb ] = (v * w [a ]) / w [b ];
295
+ } else if (Math .abs (v * w [a ] - w [b ]) >= 1e-5 ) {
296
+ return true ;
297
+ }
298
+ }
299
+
300
+ return false ;
301
+ }
84
302
```
85
303
86
304
### ** ...**
0 commit comments