【中等】力扣算法题解析LeetCode399:除法求值

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode 399. 除法求值

问题抽象: 给定一组除法等式 equations(每个等式为 [a_i, b_i, val_i] 表示 a_i / b_i = val_i)和一组查询 queries(每个查询为 [c_j, d_j]),需计算每个查询 c_j / d_j 的结果,满足以下核心需求:

  1. 计算规则

    • 利用已知等式 推导未知查询(如已知 a/b=2.0b/c=3.0,则 a/c = 2.0×3.0=6.0);
    • 若查询变量无关联或未定义,返回 -1.0
  2. 图论建模

    • 有向带权图:变量为节点,边 a→b 权重 val(表示 a/b=val),边 b→a 权重 1/val
    • 路径计算:查询 c_j/d_j 等价于从 c_jd_j 的路径权重乘积(DFS 或 BFS 遍历)。
  3. 边界处理

    • 变量未定义:若查询中的变量未出现在等式中,返回 -1.0
    • 相同变量查询c_j = d_j 时返回 1.0(即使变量未定义);
    • 无连通路径:若变量间无路径连接,返回 -1.0
    • 零除保护:输入保证等式 val_i > 0(无非正数权重)。
  4. 优化目标

    • 避免对每个查询独立遍历全图(时间复杂度 O(q·n) 不可接受,q 为查询数,n 为变量数);
    • 预处理建图后,使用 并查集Floyd 算法 预计算所有变量对的最短路径权重。
  5. 计算约束

    • 时间复杂度 O(n³ + q)
      • Floyd 算法 O(n³) 预计算所有节点对的最短路径权重;
      • 查询响应 O(1)
    • 空间复杂度 O(n²):存储所有节点对的权重矩阵;
    • 输入规模:
      • 变量数 n ≤ 20(等式数量 ≤ 20);
      • 查询数 q ≤ 20

输入:等式列表 equations(每个元素 [a_i, b_i, val_i]a_i, b_i 为字符串,val_i > 0);查询列表 queries(格式同 equations 但无权重)。
输出:浮点数数组 ansans[j] 为查询 queries[j] 的结果,无解时 -1.0)。


解题思路

该问题可以建模为带权图问题,使用带权并查集高效解决:

  1. 图建模:每个变量为节点,方程式 A/B = v 表示节点 AB 的有向边(权重 v),反向边权重为 1/v
  2. 并查集设计
    • parent[]:记录每个节点的根节点。
    • weight[]:记录节点到根节点的权重乘积(节点值 = 根节点值 × 权重)。
  3. 核心操作
    • 查找:递归寻找根节点,同时进行路径压缩和权重更新(当前权重 = 当前权重 × 父节点权重)。
    • 合并:若 A/B = v,找到根节点 rootArootB。若不同根,将 rootA 的父节点设为 rootB,并更新权重为 (v × weight[B]) / weight[A]
  4. 查询处理:对于查询 C/D
    • CD 未出现,返回 -1.0
    • 若同根,结果为 weight[C] / weight[D];否则返回 -1.0

代码实现(Java版)🔥点击下载源码

class Solution {
   
   
    public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
   
   
        // 映射变量名到唯一ID
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值