题目要求:
分析:
刚开始看这道题目的时候真的是太恶心了,密密麻麻全是字,转换一下,人家想让我们求的东西就如下图所示:
给出的方程式中有a, b, c三个变量,那么关于a, b, c之间的关系式我们都能求,但是如果是其它变量,比如进来一个e,就求不了了,于是就返回- 1.0.
x的话,如果它的值为0,那么这个表达式也没有意义,所以它返回的也是- 1.0.
这样一看就相对比较清晰了,我们可以将它看作一个图,如下所示:
这里本来只有a和b,b和c的关系式,但是a和c之间也是有关系的,这个关系可以通过a和b,b和c的关系是递推出来。在代码中,我们可以利用一个递归来实现。
所以这道题就已经转变成了一个图的问题,即求两点之间是否能找到一条边:
如果能找到,则返回权值;
如果找不到,则返回- 1。
在这里,我们使用邻接表的存储形式来对这个图进行存储。
具体代码参照了这位大神的博客:传送门:leetcode399. Evaluate Division
这位大神代码的注释非常详细,可以好好看看。
具体代码如下:
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
Map<String, List<String>> pairs = new HashMap<>();
Map<String, List<Double>> valuedPairs = new HashMap<>();
for(int i = 0 ; i < equations.size() ; i++) {
List<String> equation = equations.get(i);
//被除数
String multiplied = equation.get(0);
//除数
String multiplier = equation.get(1);//除数
if(!pairs.containsKey(multiplied)) {
pairs.put(multiplied, new ArrayList<>());
valuedPairs.put(multiplied, new ArrayList<>());
}
if(!pairs.containsKey(multiplier)) {
pairs.put(multiplier, new ArrayList<>());
valuedPairs.put(multiplier, new ArrayList<>());
}
pairs.get(multiplied).add(multiplier);
pairs.get(multiplier).add(multiplied);
valuedPairs.get(multiplied).add(values[i]);
valuedPairs.get(multiplier).add(1.0 / values[i]);
}
//结果集
double[] result = new double[queries.size()];
for(int i = 0 ; i<queries.size() ; i++) {
result[i] = dfs(queries.get(i).get(0), queries.get(i).get(1), pairs, valuedPairs, new HashSet<>(), 1.0);
result[i] = result[i]==0.0 ? -1.0 : result[i];
}
return result;
}
public double dfs(String multiplied, String multiplier, Map<String, List<String>> pairs, Map<String, List<Double>> valuedPairs, Set<String> visited, double curResult) {
if(!pairs.containsKey(multiplied))
return 0.0;
if(visited.contains(multiplied))
return 0.0;
if(multiplied.equals(multiplier))
return curResult;
visited.add(multiplied);
List<String> multipliers = pairs.get(multiplied);
List<Double> multiplierValues = valuedPairs.get(multiplied);
double tmp = 0.0;
for(int i = 0 ; i<multipliers.size() ; i++) {
tmp = dfs(multipliers.get(i), multiplier, pairs, valuedPairs, visited, curResult * multiplierValues.get(i));
if(tmp != 0.0){
break;
}
}
visited.remove(multiplied);
return tmp;
}
}