题目描述:给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。
另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。
返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。
注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
解题思路:并查集+路径压缩,代码如下:
class UnionFind(object):
def __init__(self):
self.father = {}
self.value = {}
def add(self, x):
if x not in self.father:
self.father[x] = x
self.value[x] = 1.0
def find(self, x):
root = x
base = 1.0
#查找
while self.father[root] != root:
root = self.father[root]
base *= self.value[root]
#路径压缩
while x != root:
cur_root = self.father[x]
self.value[x] *= base
base /= self.value[cur_root]
self.father[x] = root
x = cur_root
return self.father[x]
def merge(self, a, b, val):
root_a, root_b = self.find(a), self.find(b)
if root_a != root_b:
self.father[root_a] = root_b
self.value[root_a] = self.value[b] * val / self.value[a]
def isconnected(self, a, b):
return a in self.value and b in self.value and self.find(a) == self.find(b)
class Solution:
def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
uf = UnionFind()
for (a, b), val in zip(equations, values):
uf.add(a)
uf.add(b)
uf.merge(a, b, val)
res = [-1.0] * len(queries)
for i, (a, b )in enumerate(queries):
if uf.isconnected(a, b):
res[i] = uf.value[a] / uf.value[b]
return res