题目来源:LeetCode 399. 除法求值
问题抽象: 给定一组除法等式 equations(每个等式为 [a_i, b_i, val_i] 表示 a_i / b_i = val_i)和一组查询 queries(每个查询为 [c_j, d_j]),需计算每个查询 c_j / d_j 的结果,满足以下核心需求:
-
计算规则:
- 利用已知等式 推导未知查询(如已知
a/b=2.0和b/c=3.0,则a/c = 2.0×3.0=6.0); - 若查询变量无关联或未定义,返回
-1.0。
- 利用已知等式 推导未知查询(如已知
-
图论建模:
- 有向带权图:变量为节点,边
a→b权重val(表示a/b=val),边b→a权重1/val; - 路径计算:查询
c_j/d_j等价于从c_j到d_j的路径权重乘积(DFS 或 BFS 遍历)。
- 有向带权图:变量为节点,边
-
边界处理:
- 变量未定义:若查询中的变量未出现在等式中,返回
-1.0; - 相同变量查询:
c_j = d_j时返回1.0(即使变量未定义); - 无连通路径:若变量间无路径连接,返回
-1.0; - 零除保护:输入保证等式
val_i > 0(无非正数权重)。
- 变量未定义:若查询中的变量未出现在等式中,返回
-
优化目标:
- 避免对每个查询独立遍历全图(时间复杂度
O(q·n)不可接受,q为查询数,n为变量数); - 预处理建图后,使用 并查集 或 Floyd 算法 预计算所有变量对的最短路径权重。
- 避免对每个查询独立遍历全图(时间复杂度
-
计算约束:
- 时间复杂度 O(n³ + q):
- Floyd 算法
O(n³)预计算所有节点对的最短路径权重; - 查询响应
O(1);
- Floyd 算法
- 空间复杂度 O(n²):存储所有节点对的权重矩阵;
- 输入规模:
- 变量数
n ≤ 20(等式数量≤ 20); - 查询数
q ≤ 20。
- 变量数
- 时间复杂度 O(n³ + q):
输入:等式列表 equations(每个元素 [a_i, b_i, val_i],a_i, b_i 为字符串,val_i > 0);查询列表 queries(格式同 equations 但无权重)。
输出:浮点数数组 ans(ans[j] 为查询 queries[j] 的结果,无解时 -1.0)。
解题思路
该问题可以建模为带权图问题,使用带权并查集高效解决:
- 图建模:每个变量为节点,方程式
A/B = v表示节点A到B的有向边(权重v),反向边权重为1/v。 - 并查集设计:
parent[]:记录每个节点的根节点。weight[]:记录节点到根节点的权重乘积(节点值 = 根节点值 × 权重)。
- 核心操作:
- 查找:递归寻找根节点,同时进行路径压缩和权重更新(当前权重 = 当前权重 × 父节点权重)。
- 合并:若
A/B = v,找到根节点rootA和rootB。若不同根,将rootA的父节点设为rootB,并更新权重为(v × weight[B]) / weight[A]。
- 查询处理:对于查询
C/D:- 若
C或D未出现,返回-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

655

被折叠的 条评论
为什么被折叠?



