给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。
另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。
返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。
注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
输入:
equations = [[“a”,“b”],[“b”,“c”]], values = [2.0,3.0],
queries =[[“a”,“c”],[“b”,“a”],[“a”,“e”],[“a”,“a”],[“x”,“x”]]
输出:
[6.00000,0.50000,-1.00000,1.00000,-1.00000]
解释:
条件:a / b = 2.0, b /c = 3.0
问题:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
结果:[6.0, 0.5, -1.0, 1.0, -1.0 ]
常规思路,递归,先构建一个字典,默认值是空列表,然后遍历变量对数组,对于每个变量对数组分别让前一个字符串作为键,对应的值由元组构成,包括其对应的那个字符串,还有前一个字符除以后一个字符的值,让后一个字符作为键,对应的值是前一个字符和前面的比值的倒数,这样就把由一个字符到另一个字符的值都计算出来了,然后对于查询数组的两个字符串,就递归的找前一个字符串到后一个字符串的过程,将对应的值相乘就是查询数组对应的值。
循环遍历查询数组,将每一对数组的结果加进最终结果里。
以示例为例,先构建字典,字典中有{a:[(b,2)],b:[(a,1/2)(c,3)],c[(b,1/3)]},然后我们查询[a,c]这一对,传入递归函数两个字符串,值初始化为1,路径列表里先把第一个u放进去。
初始化结果为-1,然后遍历a对应的元组,得到a对应b,并且路径值为2,然后将这个b加进路径里面,这样路径里就是a,b,如果这个b正好就是后一个查询字符串,那直接返回路径值相乘即可,这里不是b是c,所以进行递归调用找b到c的路径,可以在字典中找到路径为3,这样递归最后得到路径值1×2×3=6,返回这一查询对的值为6,其他同理,当都遍历完成后,返回结果。
class Solution(object):
def calcEquation(self, equations, values, queries):
"""
:type equations: List[List[str]]
:type values: List[float]
:type queries: List[List[str]]
:rtype: List[float]
"""
g = defaultdict(list)
for i in range(len(equations)):
u, v = equations[i]
value = values[i]
g[u].append( (v, value) )
g[v].append( (u, 1 / value) )
def dfs(u, v, path_value, path):
if u not in g or v not in g:
return -1
if u == v:
return 1
ans = -1
for nxt in g[u]:
nxt_num, path_cost = nxt
if nxt_num not in path:
path.append(nxt_num)
if nxt_num == v:
return path_value*path_cost
else:
ans = dfs(nxt_num, v, path_value*path_cost, path)
if ans > 0:
return ans
return ans
res = []
for u, v in queries:
res.append(dfs(u,v,1,[u]))
return res