题目
给你一个变量对数组 equations
和一个实数值数组
values
作为已知条件,其中
equations[i] = [Ai, Bi]
和 values[i]
共同表示等式 Ai / Bi = values[i]
。每个 Ai
或
Bi
是一个表示单个变量的字符串。
另有一些以数组 queries
表示的问题,其中
queries[j] = [Cj, Dj]
表示第 j
个问题,请你根据已知条件找出 Cj / Dj = ?
的结果作为答案。
返回 所有问题的答案
。如果存在某个无法确定的答案,则用 -1.0
替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用
-1.0
替代这个答案。
注意: 输入总是有效的。你可以假设除法运算中不会出现除数为
0 的情况,且不存在任何矛盾的结果。
注意: 未在等式列表中出现的变量是未定义的,因此无法确定它们的答案。
示例 1:
1 2 3 4 5 6 7 输入:equations = [["a" ,"b" ],["b" ,"c" ]], values = [2.0 ,3.0 ], queries = [["a" ,"c" ],["b" ,"a" ],["a" ,"e" ],["a" ,"a" ],["x" ,"x" ]] 输出:[6.00000 ,0.50000 ,-1.00000 ,1.00000 ,-1.00000 ] 解释: 条件: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 ] 注意:x 是未定义的 => -1.0
示例 2:
1 2 输入:equations = [["a" ,"b" ],["b" ,"c" ],["bc" ,"cd" ]], values = [1.5 ,2.5 ,5.0 ], queries = [["a" ,"c" ],["c" ,"b" ],["bc" ,"cd" ],["cd" ,"bc" ]] 输出:[3.75000 ,0.40000 ,5.00000 ,0.20000 ]
示例 3:
1 2 输入:equations = [["a" ,"b" ]], values = [0.5 ], queries = [["a" ,"b" ],["b" ,"a" ],["a" ,"c" ],["x" ,"y" ]] 输出:[0.50000 ,2.00000 ,-1.00000 ,-1.00000 ]
提示:
1 <= equations.length <= 20
equations[i].length == 2
1 <= Ai.length, Bi.length <= 5
values.length == equations.length
0.0 < values[i] <= 20.0
1 <= queries.length <= 20
queries[i].length == 2
1 <= Cj.length, Dj.length <= 5
Ai, Bi, Cj, Dj
由小写英文字母与数字组成
题解
这一题关键是往图那边去靠:
给定图中的一些点(变量),和某些边的权值(两个变量的比值),对任意两点(两个变量)求出路径长(两个变量的比值)。
那么就需要遍历equations
,将不同的字符串映射为整数。
然后对于每一个查询,从起点出发,通过广搜的方式,不断更新起点和当前点的路径长度,直到搜索到终点为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 class Solution { public double [] calcEquation(List<List<String>> equations, double [] values, List<List<String>> queries) { int nvars = 0 ; Map<String, Integer> variables = new HashMap <String, Integer>(); int n = equations.size(); for (int i = 0 ; i < n; i++) { if (!variables.containsKey(equations.get(i).get(0 ))) { variables.put(equations.get(i).get(0 ), nvars++); } if (!variables.containsKey(equations.get(i).get(1 ))) { variables.put(equations.get(i).get(1 ), nvars++); } } List<Pair>[] edges = new List [nvars]; for (int i = 0 ; i < nvars; i++) { edges[i] = new ArrayList <Pair>(); } for (int i = 0 ; i < n; i++) { int va = variables.get(equations.get(i).get(0 )), vb = variables.get(equations.get(i).get(1 )); edges[va].add(new Pair (vb, values[i])); edges[vb].add(new Pair (va, 1.0 / values[i])); } int queriesCount = queries.size(); double [] ret = new double [queriesCount]; for (int i = 0 ; i < queriesCount; i++) { List<String> query = queries.get(i); double result = -1.0 ; if (variables.containsKey(query.get(0 )) && variables.containsKey(query.get(1 ))) { int ia = variables.get(query.get(0 )), ib = variables.get(query.get(1 )); if (ia == ib) { result = 1.0 ; } else { Queue<Integer> points = new LinkedList <Integer>(); points.offer(ia); double [] ratios = new double [nvars]; Arrays.fill(ratios, -1.0 ); ratios[ia] = 1.0 ; while (!points.isEmpty() && ratios[ib] < 0 ) { int x = points.poll(); for (Pair pair : edges[x]) { int y = pair.index; double val = pair.value; if (ratios[y] < 0 ) { ratios[y] = ratios[x] * val; points.offer(y); } } } result = ratios[ib]; } } ret[i] = result; } return ret; } }class Pair { int index; double value; Pair(int index, double value) { this .index = index; this .value = value; } }