Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.2307 #1993

Merged
merged 1 commit into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,246 @@ a = 3, b = 1 和 c = 2.

<!-- 这里可写通用的实现逻辑 -->

**方法一:带权并查集**

我们先将字符串转换成从 $0$ 开始的整数,然后遍历所有的等式,将等式中的两个字符串映射成对应的整数 $a$ 和 $b$,如果这两个整数不在同一个集合中,就将它们合并到同一个集合中,并且记录下两个整数的权值,即 $a$ 与 $b$ 的比值。如果这两个整数在同一个集合中,就判断它们的权值是否满足等式,如果不满足就返回 `true`。

时间复杂度 $O(n \times \log n)$ 或 $O(n \times \alpha(n))$,空间复杂度 $O(n)$。其中 $n$ 是等式的数量。

相似题目:

- [399. 除法求值](/solution/0300-0399/0399.Evaluate%20Division/README.md)

<!-- tabs:start -->

### **Python3**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```python

class Solution:
def checkContradictions(
self, equations: List[List[str]], values: List[float]
) -> bool:
def find(x: int) -> int:
if p[x] != x:
root = find(p[x])
w[x] *= w[p[x]]
p[x] = root
return p[x]

d = defaultdict(int)
n = 0
for e in equations:
for s in e:
if s not in d:
d[s] = n
n += 1
p = list(range(n))
w = [1.0] * n
eps = 1e-5
for (a, b), v in zip(equations, values):
a, b = d[a], d[b]
pa, pb = find(a), find(b)
if pa != pb:
p[pb] = pa
w[pb] = v * w[a] / w[b]
elif abs(v * w[a] - w[b]) >= eps:
return True
return False
```

### **Java**

<!-- 这里可写当前语言的特殊实现逻辑 -->

```java
class Solution {
private int[] p;
private double[] w;

public boolean checkContradictions(List<List<String>> equations, double[] values) {
Map<String, Integer> d = new HashMap<>();
int n = 0;
for (var e : equations) {
for (var s : e) {
if (!d.containsKey(s)) {
d.put(s, n++);
}
}
}
p = new int[n];
w = new double[n];
for (int i = 0; i < n; ++i) {
p[i] = i;
w[i] = 1.0;
}
final double eps = 1e-5;
for (int i = 0; i < equations.size(); ++i) {
int a = d.get(equations.get(i).get(0)), b = d.get(equations.get(i).get(1));
int pa = find(a), pb = find(b);
double v = values[i];
if (pa != pb) {
p[pb] = pa;
w[pb] = v * w[a] / w[b];
} else if (Math.abs(v * w[a] - w[b]) >= eps) {
return true;
}
}
return false;
}

private int find(int x) {
if (p[x] != x) {
int root = find(p[x]);
w[x] *= w[p[x]];
p[x] = root;
}
return p[x];
}
}
```

### **C++**

```cpp
class Solution {
public:
bool checkContradictions(vector<vector<string>>& equations, vector<double>& values) {
unordered_map<string, int> d;
int n = 0;
for (auto& e : equations) {
for (auto& s : e) {
if (!d.count(s)) {
d[s] = n++;
}
}
}
vector<int> p(n);
iota(p.begin(), p.end(), 0);
vector<double> w(n, 1.0);
function<int(int)> find = [&](int x) -> int {
if (p[x] != x) {
int root = find(p[x]);
w[x] *= w[p[x]];
p[x] = root;
}
return p[x];
};
for (int i = 0; i < equations.size(); ++i) {
int a = d[equations[i][0]], b = d[equations[i][1]];
double v = values[i];
int pa = find(a), pb = find(b);
if (pa != pb) {
p[pb] = pa;
w[pb] = v * w[a] / w[b];
} else if (fabs(v * w[a] - w[b]) >= 1e-5) {
return true;
}
}
return false;
}
};
```

### **Go**

```go
func checkContradictions(equations [][]string, values []float64) bool {
d := make(map[string]int)
n := 0

for _, e := range equations {
for _, s := range e {
if _, ok := d[s]; !ok {
d[s] = n
n++
}
}
}

p := make([]int, n)
for i := range p {
p[i] = i
}

w := make([]float64, n)
for i := range w {
w[i] = 1.0
}

var find func(int) int
find = func(x int) int {
if p[x] != x {
root := find(p[x])
w[x] *= w[p[x]]
p[x] = root
}
return p[x]
}
for i, e := range equations {
a, b := d[e[0]], d[e[1]]
v := values[i]

pa, pb := find(a), find(b)
if pa != pb {
p[pb] = pa
w[pb] = v * w[a] / w[b]
} else if v*w[a]-w[b] >= 1e-5 || w[b]-v*w[a] >= 1e-5 {
return true
}
}

return false
}
```

### **TypeScript**

```ts

function checkContradictions(equations: string[][], values: number[]): boolean {
const d: { [key: string]: number } = {};
let n = 0;

for (const e of equations) {
for (const s of e) {
if (!(s in d)) {
d[s] = n;
n++;
}
}
}

const p: number[] = Array.from({ length: n }, (_, i) => i);
const w: number[] = Array.from({ length: n }, () => 1.0);

const find = (x: number): number => {
if (p[x] !== x) {
const root = find(p[x]);
w[x] *= w[p[x]];
p[x] = root;
}
return p[x];
};

for (let i = 0; i < equations.length; i++) {
const a = d[equations[i][0]];
const b = d[equations[i][1]];
const v = values[i];

const pa = find(a);
const pb = find(b);

if (pa !== pb) {
p[pb] = pa;
w[pb] = (v * w[a]) / w[b];
} else if (Math.abs(v * w[a] - w[b]) >= 1e-5) {
return true;
}
}

return false;
}
```

### **...**
Expand Down
Loading