comments | difficulty | edit_url | tags | ||||
---|---|---|---|---|---|---|---|
true |
困难 |
|
给你一个由字符串二维数组 equations
和实数数组 values
,其中 equations[i] = [Ai, Bi]
,values[i]
表示 Ai / Bi = values[i]
.。
确定方程中是否存在矛盾。如果存在矛盾则返回 true
,否则返回 false
。
注意:
- 当检查两个数字是否相等时,检查它们的 绝对差值 是否小于
10-5
. - 生成的测试用例没有针对精度的用例,即使用
double
就足以解决问题。
示例 1:
输入: equations = [["a","b"],["b","c"],["a","c"]], values = [3,0.5,1.5] 输出: false 解释: 给定的方程为: a / b = 3, b / c = 0.5, a / c = 1.5 方程中没有矛盾。满足所有方程的一个可能的分配是: a = 3, b = 1 和 c = 2.
示例 2:
输入: equations = [["le","et"],["le","code"],["code","et"]], values = [2,5,0.5] 输出: true 解释: 给定的方程为: le / et = 2, le / code = 5, code / et = 0.5 根据前两个方程,我们得到 code / et = 0.4. 因为第三个方程是 code / et = 0.5, 所以矛盾。
提示:
1 <= equations.length <= 100
equations[i].length == 2
1 <= Ai.length, Bi.length <= 5
Ai
,Bi
由小写英文字母组成。equations.length == values.length
0.0 < values[i] <= 10.0
values[i]
小数点后最多 2 位。
我们先将字符串转换成从 true
。
时间复杂度
相似题目:
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
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];
}
}
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;
}
};
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
}
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;
}