You are given an array of variable pairs equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string that represents a single variable.
You are also given some queries, where queries[j] = [Cj, Dj] represents the jth query where you must find the answer for Cj / Dj = ?.
Return the answers to all queries. If a single answer cannot be determined, return -1.0.
Note: The input is always valid. You may assume that evaluating the queries will not result in division by zero and that there is no contradiction.
Note: The variables that do not occur in the list of equations are undefined, so the answer cannot be determined for them.
Example 1:
Input: equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]] Output: [6.00000,0.50000,-1.00000,1.00000,-1.00000] Explanation: 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 ] note: x is undefined => -1.0
Example 2:
Input: equations = [["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0], queries = [["a","c"],["c","b"],["bc","cd"],["cd","bc"]] Output: [3.75000,0.40000,5.00000,0.20000]
Example 3:
Input: equations = [["a","b"]], values = [0.5], queries = [["a","b"],["b","a"],["a","c"],["x","y"]] Output: [0.50000,2.00000,-1.00000,-1.00000]
Constraints:
1 <= equations.length <= 20equations[i].length == 21 <= Ai.length, Bi.length <= 5values.length == equations.length0.0 < values[i] <= 20.01 <= queries.length <= 20queries[i].length == 21 <= Cj.length, Dj.length <= 5Ai, Bi, Cj, Dj consist of lower case English letters and digits.class Solution {
record Pair(String num, String den) {
}
Map<Pair, Double> memo = new HashMap<>();
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
Map<String, Map<String, Double>> adj = new HashMap<>();
for (int i = 0; i < values.length; i++) {
List<String> eqn = equations.get(i);
adj.putIfAbsent(eqn.get(0), new HashMap<>());
adj.putIfAbsent(eqn.get(1), new HashMap<>());
adj.get(eqn.get(0)).put(eqn.get(1), values[i]);
adj.get(eqn.get(1)).put(eqn.get(0), 1/values[i]);
}
// System.out.println(adj);
double[] ans = new double[queries.size()];
for (int i = 0; i < queries.size(); i++) {
List<String> q = queries.get(i);
String src = q.get(0), dest = q.get(1);
if (!adj.containsKey(src))
ans[i] = -1d;
else if (memo.containsKey(new Pair(src, dest)))
ans[i] = memo.get(new Pair(src, dest));
else {
dfs(adj, new HashSet<>(), src, src, dest, 1d);
ans[i] = memo.getOrDefault(new Pair(src, dest), -1d);
}
}
return ans;
}
private void dfs(Map<String, Map<String, Double>> adj, Set<String> vis, String src, String curr, String dest,
double prob) {
vis.add(curr);
memo.put(new Pair(src, curr), prob);
memo.put(new Pair(curr, src), 1/prob);
if (curr.equals(dest))
return;
for (Map.Entry<String, Double> nbr : adj.get(curr).entrySet())
if (!vis.contains(nbr.getKey()))
dfs(adj, vis, src, nbr.getKey(), dest, prob * nbr.getValue());
}
}