@@ -59,28 +59,246 @@ a = 3, b = 1 和 c = 2.
5959
6060<!-- 这里可写通用的实现逻辑 -->
6161
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+
6272<!-- tabs:start -->
6373
6474### ** Python3**
6575
6676<!-- 这里可写当前语言的特殊实现逻辑 -->
6777
6878``` 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
70109```
71110
72111### ** Java**
73112
74113<!-- 这里可写当前语言的特殊实现逻辑 -->
75114
76115``` 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+ ```
77161
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+ }
78254```
79255
80256### ** TypeScript**
81257
82258``` 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+ }
84302```
85303
86304### ** ...**
0 commit comments