Leetcode-399. 除法求值 Evaluate Division (并查集Union-Find) -超详细python

该博客主要讲解了如何使用Python实现LeetCode上的399题——除法求值。通过并查集(Union-Find)的数据结构,解决根据给定的方程式求解变量间的关系,并对一系列查询进行回答。文章提供了详细的思路解析和代码实现,并分析了算法的时间复杂度为O(n)和空间复杂度也为O(n)。

题目

给出方程式 A / B = k, 其中 A 和 B 均为用字符串表示的变量, k 是一个浮点型数字。根据已知方程式求解问题,并返回计算结果。如果结果不存在,则返回 -1.0。
链接:https://leetcode.com/problems/evaluate-division/

Equations are given in the format A / B = k, where A and B are variables represented as strings, and k is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0.

Example:

Input: equations = [ [“a”, “b”], [“b”, “c”] ],
values = [2.0, 3.0],
queries = [ [“a”, “c”], [“b”, “a”], [“a”, “e”], [“a”, “a”], [“x”, “x”] ].
Output: [6.0, 0.5, -1.0, 1.0, -1.0 ].

思路及代码

并查集 Union-Find
  • Union-Find的思想是给所有的元素找到同样的根,并集时要合并为相同根
  • 本题对每一个元素存储为在字典中:key: [root, value],其中key = root * value
    • 比如x/y = 2则x:[y,2]和y:[y,1]
  • 在最后计算答案的时候,溯源到根节点:x = root * vx, y = root * vy,则x/y = vx / vy,若找不到相同的根节点则返回-1
class Solution:
    def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
        def find(x):
            if x != U[x][0]:
            	# U[x][0] = rx * vx
                rx, vx = find(U[x][0])
                # U[x] = U[x][0] * U[x][1] = rx * vx * U[x][1]
                U[x] = [rx, U[x][1]*vx]
            return U[x]
        
        def divide(x,y):
        	# x = rx * ry
            rx, vx = find(x)
            # y = ry * vy
            ry, vy = find(y)
            if rx != ry:
                return -1
            # rx == ry: x/y = vx/vy
            return vx / vy
        
        U = {}
        # x/y = v
        for (x,y), v in zip(equations, values):
            if x not in U and y not in U:
                U[x] = [y, v]
                U[y] = [y, 1.0]
            elif x not in U:
            	# U[y][0] * U[y][1] = y
            	# y * v = x
                U[x] = [U[y][0], v * U[y][1]]
            elif y not in U:
                U[y] = [U[x][0], U[x][1] / v]
            else:
                rx, vx = find(x)
                ry, vy = find(y)
                # rx * vx = x, ry * vy = y, x = y * v
                # rx = ry * v * vy / vx
                # 将x的原根节点合并给y,更新为y的根节点
                U[rx] = [ry, v*vy / vx]
        
        ans = [divide(x,y) if x in U and y in U else -1 for x,y in queries]
        return ans

复杂度

T=O(n)T = O(n)T=O(n)
S=O(n)S = O(n)S=O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值