提示
给你一个变量对数组
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:
输入: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:
输入: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:
输入: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 由小写英文字母与数字组成
思路
创建一个hashMap> 的数据结构,用来存储 a和b的关系以及他们的除法结果,同时记录b / a 的除法结果 1 / v。
我们的函数最终返回res这个数组,我们把他全部初始化为 -1
接下来我们编写深度搜索函数,这里设置了七个参数,他们的含义分别是
src |
起点 |
dst | 终点 |
curVal | 当前的计算结果 |
graph | 图 |
index | 最初开始的起点的索引 |
res | 最终返回结果 |
visited | 存储访问过的节点 |
我们在递归函数的入口设置curVal为 1,这是因为当这次查询的起点就是终点的时候我们我们的路径计算结果就是1
关于递归函数的出口,当我们的src被访问过时,我们就不再执行函数;当起点等于终点的时候,我们判断一下他们在不在图中,防止有两个不被输入的字符相除,如果他们在图中,记录此时的curVal到res中去,然后终止函数
在递归的过程中,我们要讲curVal 更新为 curVal*nei.div 这是因为nei.str为我们搜索的尾节点,他当前的值curVal是他过去经历的边的乘积。
代码
class Solution { public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) { Map<String,List<Cell>> graph = new HashMap<>(); for(int i = 0;i < values.length;i++){ String s1 = equations.get(i).get(0),s2 = equations.get(i).get(1); graph.computeIfAbsent(s1,k->new ArrayList<>()).add(new Cell(s2,values[i])); graph.computeIfAbsent(s2,k->new ArrayList<>()).add(new Cell(s1,1.0 / values[i])); } double[] res = new double[queries.size()]; Arrays.fill(res,-1.0); for(int i = 0;i<queries.size();i++){ Set<String> visited = new HashSet<>(); dfs(queries.get(i).get(0),queries.get(i).get(1), 1.0 ,graph,res,i,visited); } return res; } public void dfs(String src,String dst,double curVal,Map<String,List<Cell>> graph,double[] res,int index,Set<String> visited){ if(!visited.add(src)){ return; } if(src.equals(dst) && graph.containsKey(src)){ res[index] = curVal; return; } for(Cell nei:graph.getOrDefault(src,new ArrayList<>())){ dfs(nei.str,dst,curVal*nei.div,graph,res,index,visited); } } } class Cell{ String str; double div; Cell(String str,double div){ this.str = str; this.div = div; } }