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>> euqations,
vector<double>& values, vector<pair<string,
string>> query
. where equations.size() == values.size()
,the values are positive. this represents the equations.return vector<double>.
.
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.
Analysis:
We need to build a graph to describe the input equations: for equations[i], equations[i][0] -> equations[i][1] = values[i] while equations[i][1] -> equations[i][0] = 1/values[i].
After getting the graph, we can search the graph for each query. During every search, we record each calculated result in the graph for later use.
NOTE: to be compatiable with possible values[i] == 0, we can use Double type instead of double type. For x/y==0, we do not record y/x, i.e., set y/x as null.
Solution:
public class Solution { public double[] calcEquation(String[][] equations, double[] values, String[][] query) { HashMap<String,Integer> indexMap = new HashMap<String,Integer>(); int nums = 0; for (String[] equation : equations){ if (!indexMap.containsKey(equation[0])){ indexMap.put(equation[0],nums++); } if (!indexMap.containsKey(equation[1])){ indexMap.put(equation[1],nums++); } } Double[][] graph = new Double[nums][nums]; for (int i=0;i<equations.length;i++){ int num1 = indexMap.get(equations[i][0]), num2 = indexMap.get(equations[i][1]); if (values[i]!=0){ graph[num2][num1] = 1/values[i]; } graph[num1][num2] = values[i]; graph[num1][num1] = 1.0; graph[num2][num2] = 1.0; } double[] res = new double[query.length]; for (int i=0;i<query.length;i++){ if (!indexMap.containsKey(query[i][0]) || !indexMap.containsKey(query[i][1])){ res[i] = -1; } else { int num1 = indexMap.get(query[i][0]), num2 = indexMap.get(query[i][1]); res[i] = calcQuery(graph,num1,num2); } } return res; } public double calcQuery(Double[][] graph, int start, int end){ if (graph[start][end]!= null){ return graph[start][end]; } Queue<Integer> queue = new LinkedList<Integer>(); for (int i=0;i<graph.length;i++) if (graph[start][i]!=null){ queue.add(i); } while (!queue.isEmpty()){ int cur = queue.poll(); for (int i=0;i<graph.length;i++) if (graph[cur][i]!=null && graph[start][i]==null){ graph[start][i] = graph[start][cur]*graph[cur][i]; graph[i][start] = 1/graph[start][i]; queue.add(i); if (i==end){ return graph[start][end]; } } } return -1.0; } }