|
| 1 | +""" |
| 2 | +Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number |
| 3 | +(floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0. |
| 4 | +
|
| 5 | +Example: |
| 6 | +Given a / b = 2.0, b / c = 3.0. |
| 7 | +queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . |
| 8 | +return [6.0, 0.5, -1.0, 1.0, -1.0 ]. |
| 9 | +
|
| 10 | +The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries , |
| 11 | +where equations.size() == values.size(), and the values are positive. This represents the equations. Return |
| 12 | +vector<double>. |
| 13 | +
|
| 14 | +According to the example above: |
| 15 | +
|
| 16 | +equations = [ ["a", "b"], ["b", "c"] ], |
| 17 | +values = [2.0, 3.0], |
| 18 | +queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. |
| 19 | +
|
| 20 | +""" |
| 21 | +from collections import defaultdict |
| 22 | +from itertools import izip |
| 23 | + |
| 24 | +__author__ = 'Daniel' |
| 25 | + |
| 26 | + |
| 27 | +class Solution(object): |
| 28 | + def calcEquation(self, equations, values, queries): |
| 29 | + """ |
| 30 | + transitive closure |
| 31 | + :type equations: List[List[str]] |
| 32 | + :type values: List[float] |
| 33 | + :type queries: List[List[str]] |
| 34 | + :rtype: List[float] |
| 35 | + """ |
| 36 | + G = defaultdict(dict) |
| 37 | + for edge, val in izip(equations, values): |
| 38 | + s, e = edge |
| 39 | + G[s][e], G[e][s] = val, 1/val |
| 40 | + G[s][s], G[e][e] = 1, 1 |
| 41 | + |
| 42 | + return [self.dfs(G, s, e, set()) for s, e in queries] |
| 43 | + |
| 44 | + def dfs(self, G, s, e, path): |
| 45 | + if s not in G or e not in G: |
| 46 | + return -1.0 |
| 47 | + if e in G[s]: |
| 48 | + return G[s][e] |
| 49 | + for nbr in G[s]: |
| 50 | + if nbr not in path: |
| 51 | + path.add(nbr) |
| 52 | + val = self.dfs(G, nbr, e, path) |
| 53 | + if val != -1.0: |
| 54 | + return val * G[s][nbr] |
| 55 | + path.remove(nbr) |
| 56 | + |
| 57 | + return -1.0 |
| 58 | + |
| 59 | + |
| 60 | +class Solution(object): |
| 61 | + def calcEquation(self, equations, values, queries): |
| 62 | + """ |
| 63 | + Floyd-Warshall algorithm |
| 64 | + transitive closure |
| 65 | + :type equations: List[List[str]] |
| 66 | + :type values: List[float] |
| 67 | + :type queries: List[List[str]] |
| 68 | + :rtype: List[float] |
| 69 | + """ |
| 70 | + G = defaultdict(dict) |
| 71 | + for edge, val in izip(equations, values): |
| 72 | + s, e = edge |
| 73 | + G[s][e], G[e][s] = val, 1/val |
| 74 | + G[s][s], G[e][e] = 1, 1 |
| 75 | + |
| 76 | + # Floyd-Warshall |
| 77 | + for mid in G: |
| 78 | + for s in G[mid]: |
| 79 | + for e in G[mid]: |
| 80 | + G[s][e] = G[s][mid] * G[mid][e] |
| 81 | + |
| 82 | + return [G[s].get(e, -1.0) for s, e in queries] |
| 83 | + |
0 commit comments