原题
Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.
Example:
Given a / b = 2.0, b / c = 3.0.
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
return [6.0, 0.5, -1.0, 1.0, -1.0 ].
The input is: vector<pair<string, string>> equations, vector& values, vector<pair<string, string>> queries , where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector.
According to the example above:
equations = [ [“a”, “b”], [“b”, “c”] ],
values = [2.0, 3.0],
queries = [ [“a”, “c”], [“b”, “a”], [“a”, “e”], [“a”, “a”], [“x”, “x”] ].
The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.
解法
https://www.youtube.com/watch?v=UwpvInpgFmo
graph + DFS. 首先定义graph是键为数字, 值为字典的字典. 遍历zip(equation, values), 构建字典. 定义dfs函数, 返回x/y的商, 遍历graph[x], 将已访问过的n加到visited中. 递推方程为:
division(x, y) = division(x, n) * division(n, y)
dfs(x, y) = graph[x][n] * dfs(n, y)
代码
class Solution:
def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
def dfs(x, y, graph, visited):
# return the result of x/y if both x and y in graph
if x not in graph or y not in graph:
return -1
if x == y: return 1
for n in graph[x]:
if n in visited:
continue
visited.add(n)
d = dfs(n, y, graph, visited)
if d != -1:
return graph[x][n]*d
return -1
graph = collections.defaultdict(dict)
for (x, y), val in zip(equations, values):
graph[x][y] = val
graph[y][x] = 1.0/val
return [dfs(x, y, graph, set()) for x, y in queries]