399. 除法求值

2021-09-28  本文已影响0人  justonemoretry
image.png

解法

并查集的思想,将数组转化为图中的权重边,并进行缩短路径,每个都指向根节点

class Solution {
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
        int size = equations.size();
        // indexMap保存字符串对应的下标映射,方便UnionFind里维护数组
        Map<String, Integer> indexMap = new HashMap(size * 2);
        UnionFind unionFind = new UnionFind(size * 2);
        int index = 0;
        for (int i = 0; i < size; i++) {
            List<String> equation = equations.get(i);
            String v1 = equation.get(0);
            String v2 = equation.get(1);

            if (!indexMap.containsKey(v1)) {
                indexMap.put(v1, index++);
            }
            if (!indexMap.containsKey(v2)) {
                indexMap.put(v2, index++);
            }
            unionFind.union(indexMap.get(v1), indexMap.get(v2), values[i]);
        }

        int queriesSize = queries.size();
        double[] res = new double[queriesSize];
        for (int i = 0; i < queriesSize; i++) {
            List<String> query = queries.get(i);
            String v1 = query.get(0);
            String v2 = query.get(1);
            // 获取映射
            Integer id1 = indexMap.get(v1);
            Integer id2 = indexMap.get(v2);
            if (id1 == null || id2 == null) {
                res[i] = -1.0d;
            } else {
                res[i] = unionFind.isConnected(id1, id2);
            }
        }
        return res;
    }

    private class UnionFind {
        // 父节点是哪个
        private int[] parent;
        // 以当前点为起始点,parent对应的值为终点,对应的权重边
        private double[] weight;

        public UnionFind(int n) {
            this.parent = new int[n];
            this.weight = new double[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
                weight[i] = 1.0d;
            }
        }

        // 寻找x对应的根节点,并计算到根节点的权重值
        public int find(int x) {
            if (x != parent[x]) {
                int origin = parent[x];
                parent[x] = find(parent[x]);
                weight[x] *= weight[origin];
            }
            return parent[x];
        }

        public void union(int x, int y, double value) {
            int RootX = find(x);
            int RootY = find(y);
            if (RootX == RootY) {
                return;
            }

            parent[RootX] = RootY;
            weight[RootX] = value * weight[y] / weight[x];      
        }

        public double isConnected(int x, int y) {
            int RootX = find(x);
            int RootY = find(y);
            if (RootX == RootY) {
                return weight[x] / weight[y];
            } else {
                return -1.0d;
            }
        }
    } 
}

上一篇 下一篇

猜你喜欢

热点阅读