399.除法求值

https://leetcode-cn.com/problems/evaluate-division/

一、并查集+压缩路径

参考https://leetcode-cn.com/problems/evaluate-division/solution/399-chu-fa-qiu-zhi-nan-du-zhong-deng-286-w45d/

难点在于压缩路径

class UnionFind:
    # 构造函数传入totalNodes为总节点数
    def __init__(self, totalNodes):
        # parents[i]表示i的根,初始i的根为其自身
        self.parents = [i for i in range(totalNodes)]
        # 到根节点的权值
        self.weight = [1.0] * totalNodes
    # 因为是将x指向y,即y离终点更近,因此以y的根rootY为rootX的根
    def union(self, x, y, value):
        rootX = self.find(x)
        rootY = self.find(y)
        # 若连通则跳过
        if rootX == rootY:
            return
        self.parents[rootX] = rootY

        self.weight[rootX] = self.weight[y] * value / self.weight[x]

    # 查找最终的根
    def find(self, node):
        # 尾递归,最终路径上所有节点的父结点都指向根
        if node != self.parents[node]:
            # 先记录本层的父,用于计算权重
            old = self.parents[node]
            # 更新本层node的父
            self.parents[node] = self.find(self.parents[node])
            # 更新权重
            self.weight[node] *= self.weight[old]
        return self.parents[node]   #本层node的父传给上一层

class Solution:
    def calcEquation(self, equations, values, queries):
        map = {}
        n = 0
        # 每个变量映射到0~n-1,作为并查集的结点
        for x, y in equations:
            if x not in map:
                map[x] = n
                n += 1
            if y not in map:
                map[y] = n
                n += 1
        uf = UnionFind(n)
        # 处理所有顶点和边
        for i in range(len(equations)):
            # 变量转换为节点
            x, y = equations[i][0], equations[i][1]
            nodeX, nodeY =  map.get(x), map.get(y)
            value = values[i]
            # 连通两个点
            uf.union(nodeX, nodeY, value)

        res = []
        for x, y in queries:
            # 变量有一个不存在,直接返回-1
            if x not in map or y not in map:
                res.append(-1.0)
            else:
                nodeX, nodeY = map.get(x), map.get(y)
                rootX = uf.find(nodeX)
                rootY = uf.find(nodeY)
                if rootX == rootY:
                    res.append(uf.weight[nodeX] / uf.weight[nodeY])
                else:   # 若不连通,直接返回-1
                    res.append(-1.0)
        return res

最后更新于