Skip to content

Commit f9d54b2

Browse files
authored
feat: add solutions to lc problem: No.2307 (#1993)
No.2307.Check for Contradictions in Equations
1 parent 65b12f5 commit f9d54b2

File tree

7 files changed

+639
-2
lines changed

7 files changed

+639
-2
lines changed

solution/2300-2399/2307.Check for Contradictions in Equations/README.md

+220-2
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)