题目描述
给出方程式 A / B = k, 其中 A 和 B 均为用字符串表示的变量, k 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 -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 ]
示例 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 <= equations[i][0].length, equations[i][1].length <= 5
values.length == equations.length
0.0 < values[i] <= 20.0
1 <= queries.length <= 20
queries[i].length == 2
1 <= queries[i][0].length, queries[i][1].length <= 5
equations[i][0], equations[i][1], queries[i][0], queries[i][1] 由小写英文字母与数字组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/evaluate-division
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
- 找一个公共祖先,比如求a / b,实际上是求a / root 除以 b / root,这里我们使用并查集,但不压缩路径。
- 因为要记录除得得结果,因此还需要有一个map来记录除以root的值,高端点也可以叫做权重。
- 首先初始化每个数的root是自己,且权重为1。
- 根据已知条件,将equations中的两个数进行合并,equation[i][0]的根节点如果和equations[i][1]的根节点不相同的话,设equations[i][0]的根节点设为equations[i][0]的根节点的子节点,并更新权重/好绕啊,实际代码如下
parent.put(p1.getKey(), p2.getKey()); weight.put(p1.getKey(), val * p2.getValue() / p1.getValue());
- getPair函数中,实现了查找输入节点的root节点并返回权重的功能
代码
class Solution {
HashMap<String, String> parent = new HashMap<>();
HashMap<String, Double> weight = new HashMap<>();
// Pair<String, Double> String是祖先节点,Double是权重
public Pair<String, Double> getPair(String node){
if(!parent.containsKey(node)){
return new Pair<String, Double>("", -1.0);
}
double _weight = 1;
while(parent.get(node) != node){
// a/c = a/b * b/c,所以一直是乘的关系。
_weight *= weight.get(node);
node = parent.get(node);
}
return new Pair<>(node, _weight);
}
private void combine(String a, String b, double val){
Pair<String, Double> p1 = getPair(a);
Pair<String, Double> p2 = getPair(b);
if(p1.getKey() == "" || p2.getKey() == "" ) return;
if(p1.getKey() == p2.getKey()) return;
parent.put(p1.getKey(), p2.getKey());
weight.put(p1.getKey(), val * p2.getValue() / p1.getValue());
}
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
double[] res = new double[queries.size()];
int i = 0;
for(List<String> item : equations){
if(getPair(item.get(0)).getKey() == ""){
parent.put(item.get(0), item.get(0));
weight.put(item.get(0), 1.0);
}
if(getPair(item.get(1)).getKey() == ""){
parent.put(item.get(1), item.get(1));
weight.put(item.get(1), 1.0);
}
combine(item.get(0), item.get(1), values[i++]);
}
i = 0;
for(List<String> item : queries){
Pair<String, Double> p1 = getPair(item.get(0));
Pair<String, Double> p2 = getPair(item.get(1));
if(!parent.containsKey(p1.getKey()) || !parent.containsKey(p2.getKey()) || p1.getKey() != p2.getKey()){
res[i++] = -1.0;
} else {
// a/b = (a*d*e*f) / (b*d*e*f)
res[i++] = p1.getValue() / p2.getValue();
}
}
return res;
}
}