LeetCode-Python-399. 除法求值

给出方程式 A / B = k, 其中 A 和 B 均为代表字符串的变量, k 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 -1.0

示例 :
给定 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 ]

输入为: vector> equations, vector& values, vector> queries(方程式,方程式结果,问题方程式), 其中 equations.size() == values.size(),即方程式的长度与方程式结果长度相等(程式与结果一一对应),并且结果值均为正数。以上为方程式的描述。 返回vector类型。

基于上述例子,输入如下:

equations(方程式) = [ ["a", "b"], ["b", "c"] ],
values(方程式结果) = [2.0, 3.0],
queries(问题方程式) = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. 

输入总是有效的。你可以假设除法运算中不会出现除数为0的情况,且不存在任何矛盾的结果。

思路:

建图然后DFS搜索。

a -> b 这条路的weight 是2.0, b - > c的weight是3.0,

求a -> c的结果就是求从a出发到c的一条路径,并返回路径上所有weight 的乘积。

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]
        """
        from collections import defaultdict
        graph = defaultdict(set)
        weight = defaultdict()
        
        for i, equation in enumerate(equations):
            start, end = equation[0], equation[1]
            graph[start].add(end) #设置从start到end 的path     
            weight[(start, end)] = values[i] #给上一行设置的path分配weight
            graph[end].add(start) #设置从end到start的path
            weight[(end, start)] = 1.0 / values[i] #给上一行设置的path分配weight
            
        # print weight    
        def dfs(start, end, visited):
            if (start, end) in weight: #如果可以直接读出结果
                return weight[(start, end)] #就直接返回
            
            if start not in graph or end not in graph: #这两个点根本没出现过
                return 0
            
            if start in visited: #已经形成路径环了还没找到结果
                return 0
            
            visited.add(start) #标记一下start来过了
            res = 0
            
            for tmp in graph[start]:#遍历所有能从start出发的路径
                res = weight[(start, tmp)] * dfs(tmp, end, visited)
                if res != 0: #找到了第一条路
                    weight[(start, end)] = res #把这一条路的weight记录下来
                    break
            visited.remove(start) #回溯
            # print res
            return res
        
        res = []
        for query in queries:
            tmp = dfs(query[0], query[1], set())
            if tmp == 0: #如果没找到
                tmp = -1.0
            res.append(tmp)
            
        return res

 

你可能感兴趣的:(Leetcode)