【LeetCode】399. 除法求值 并查集

在这里插入图片描述
在这里插入图片描述

这道题目的解法是带权值的并查集。

并查集

可以看这篇文章的讲解:

https://blog.csdn.net/niushuai666/article/details/6662911

并查集由一个整数型的数组和两个函数构成。数组pre[]记录了每个点的前导点是什么,函数find是查找,join是合并

解题思路:建立两个map,一个map存储上一级结点。一个map存储比值。首先不断构建查并集结构。如果两者根节点不一致,进行合并。然后输出最终的结果即可。

在这里插入图片描述

public class Solution {
    HashMap<String, String> path = new HashMap<>();  // key是当前结点,value是父结点
    HashMap<String, Double> value = new HashMap<>();  // key是当前结点,value是父结点/此结点

    public double[] calcEquation(List<List<String>> equations,
                                 double[] values,
                                 List<List<String>> queries) {
        // 这道题目用并查集的方式来求解。
        // 带权值的并查集。
        for (int i = 0; i < values.length; i++) {// 遍历被除数,除数,商。
            String parent = equations.get(i).get(0);
            String child = equations.get(i).get(1);
            double divide = values[i];
            // 首先保证 map中有这两个结点。
            if (!path.containsKey(parent)) {
                path.put(parent, parent);
                value.put(parent, 1.0);
            }
            if (!path.containsKey(child)) {
                path.put(child, child);
                value.put(child, 1.0);
            }
            String root1 = findRoot(parent);// 找到了parent的根节点
            String root2 = findRoot(child);// 找到了,child的根节点
            // 分成两种情况,两者根节点一致;两者根节点不一致。
            // 一致的话,不用管了。不一致的话,进行根节点的合并。
            if(!root1.equals(root2)){
                path.put(root2,root1);
                value.put(root2,divide*value.get(parent)/value.get(child));
            }
        }
        // 现在已经将数据按照并查集的格式存储好了
        double[] res = new double[queries.size()];
        for (int i = 0; i< queries.size(); i++) {
            List<String> query = queries.get(i);
            String s1 = query.get(0);
            String s2 = query.get(1);
            if(!(path.containsKey(s1)&&path.containsKey(s2))){
                res[i] = -1.0;
                continue;
            }
            // 说明 两者都包括
            String root1 = findRoot(s1);
            String root2 = findRoot(s2);
            if(!root1.equals(root2)){
                res[i] = -1.0;
                continue;
            }
            // 说明 两者的根结点一致。
            res[i] = value.get(s2)/value.get(s1);
        }
        return res;
    }

    private String findRoot(String str) {
        // 这个方法能够找到,str的根结点。
        // 并且最终将此结点直接与根节点相连。(设置其value值)
        String save = str;
        double divide = 1.0;
        if (path.get(str).equals(str)) {
            return str;
        }
        // 说明root不是自己。
        while (!path.get(str).equals(str)) {
            // 如果str的父结点 不等于 str
            divide *= value.get(str);
            str = path.get(str);
        }
        divide *= value.get(str);
        path.put(save, str);
        value.put(save, divide);
        return str;
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章