以下文章来源于Techdemic ,作者无锋 https://mp.weixin.qq.com/s/9cmj3lPsIoyvVzKMZDekXg#
今天休闲一下,分享一道LeetCode上medium难度的题目:Evaluate Division
https://leetcode.com/problems/evaluate-division/
** 题目详情 ** 翻译如下:
给定一组格式为 A/B=k 的方程式,再给出一组格式为 C/D 的求值式,要求得到求值式的所有值,如果值无法求出,则赋值-1.0
例子:
方程式 = [“a/b=2.0”,“b/c=3.0”]
求值式 = [“b/a”,“a/c”,“a/e"]
答案 = [0.5,6.0,-1.0]
** 分析 ** 这道题给出的方程式都是两个值之间的比值,每个方程式的分子和分母可能会有重复,并且求值式涉及到的两个值可能出现在不同的方程式中,比如在以上例子中,要求求出 a/c 的值,但是 a和 c分别出现在不同的方程式中,如何找出不同方程式中值的关系,是此题的一大难点。
仔细想的话其实不难想到一个方程组其实是一个双向连接图,每个值是一个节点,每个方程式代表了两个节点之间的连接,而相除得到的值可以看为边的权重。当我们确定一个起始节点A和目标节点B时,我们可以通过一次深度第一搜索(DFS)来得到两者之间的比值,而这个比值则是搜索路径所有边权重的乘积,如下图所示, a/c的值为 2*3=6。
值得注意的是,在双向连接图中进行DFS时需要记录一下已经到达过的节点,不然会陷入无限循环之中,以下是完整的python代码:
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]
"""
# construct a bi-directional graph with a nested dict
graph = dict()
for idx in range(0, len(equations)):
equation = equations[idx]
numerator = equation[0]
denominator = equation[1]
if graph.get(denominator) is None:
# self connecting
graph[denominator] = {denominator: 1.0}
if graph.get(numerator) is None:
graph[numerator] = {numerator: 1.0}
graph[numerator][denominator] = values[idx]
graph[denominator][numerator] = 1 / values[idx]
results = list()
for query in queries:
visited = set()
val, _ = self.dfs(graph, visited, query[0], query[1])
results.append(val)
return results
def dfs(self, graph, visited, src, dst):
visited.add(src)
src_node = graph.get(src)
if src_node is None:
return -1.0, False
val = src_node.get(dst)
if val is not None:
return val, True
for connection in src_node:
if connection in visited:
continue
val, exists = self.dfs(graph, visited, connection, dst)
if not exists:
continue
return src_node[connection] * val, True
return -1.0, False