L399. 除法求值

  1. 除法求值
    给你一个变量对数组 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 ]

1.原理介绍
在这里插入图片描述
此为union的原理
在这里插入图片描述
在这里插入图片描述

class Solution {
    private Map<String, String>  parents = new HashMap<>();
    //类似于parents[]数组
    private Map<String, Double> values = new HashMap<>();
    //因为要记录权值,新设一个map,表示父节点/当前的节点
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
        //先建立点的关系,union
        int len = equations.size();
        for(int i = 0; i < len; i++){
            String x = equations.get(i).get(0);
            String y = equations.get(i).get(1);
            union(x, y, values[i]);
        }
        len = queries.size();
        double[] ans = new double[len];
        for(int i = 0; i < len; i++){
            String x = queries.get(i).get(0);
            String y = queries.get(i).get(1);
            if(!(parents.containsKey(x) && parents.containsKey(y))){
                //只要有一个不存在,
                ans[i] = -1;
                continue;
            }
            if(x.equals(y)){
                ans[i] = 1;
                continue;
            }
            //如果不相同,找到各自根节点,先判断二者是否连通
            String r1 = findParent(x);
            String r2 = findParent(y);
            if(!r1.equals(r2)){
                ans[i] = -1;
                continue;
            }
            //最后一种情况,确是二者处于连通状态
            ans[i] = pm(y) / pm(x);//x/y恰好为二者的pm的相反数
        }
        return ans;
    }
    public void union(String x, String y, double val){
        //已经包含了加入元素的操作
        add(x);
        add(y);
        //找到各自的根节点
        String r1 = findParent(x);
        String r2 = findParent(y);
        if(!r1.equals(r2)){
            //parents.put(r1, r2);//注意这里不能写反了,前面的为子节点
            parents.put(r2, r1);
            //关键对应的权值数组/map也要进行更新
            values.put(r2, val * (pm(x) / pm(y)));
            //此时更新的就是两个找到的根节点的权值之比,恰为x/y * pm(x)/pm(y)
        }
    }
    public double pm(String x){
        //表示x节点的权值到根节点权值的乘积
        double val = 1;
        while(!x.equals(parents.get(x))){
            val *= values.get(x);
            x = parents.get(x);
        }
        return val;
    }
    public String findParent(String x){
        while(!x.equals(parents.get(x))){
            //其实形式是差不多的
            x = parents.get(x);
        }
        return x;
    }
    public void add(String now){
        if(!parents.containsKey(now)){
            parents.put(now, now);
            values.put(now, 1.0);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值