【广度优先搜索】No. 0399 除法求值【中等】👉力扣对应题目指路
![](https://i-blog.csdnimg.cn/direct/53543a8b255e4c448d799a2bc1475df5.png)
希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦
欢迎关注、订阅专栏 【力扣详解】谢谢你的支持!
⭐ 题目描述:给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。
-
返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。
-
注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
-
注意:未在等式列表中出现的变量是未定义的,因此无法确定它们的答案。
-
示例 1:
输入:equations = [[“a”,“b”],[“b”,“c”]], values = [2.0,3.0], queries = [[“a”,“c”],[“b”,“a”],[“a”,“e”],[“a”,“a”],[“x”,“x”]]
输出:[6.00000,0.50000,-1.00000,1.00000,-1.00000]
解释:
条件:a / b = 2.0, b / c = 3.0
问题:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
结果:[6.0, 0.5, -1.0, 1.0, -1.0 ]
注意:x 是未定义的 => -1.0
🔥 思路:【广度优先搜索】将变量转为节点,除法转为带权重的有向边
- 那么对于 queries[j] = [Cj, Dj],也就是找
C_j
到D_j
的路径并累乘路径涉及到的边
参考如上思路,给出详细步骤如下:
- 步骤一⭐生成图:双层哈希表【一个大哈希表 (key: node, value: node 对应的邻居哈希表),存储每个节点对应的邻居哈希表 (key: 邻居 node, value: node / 邻居 node 的值)】
- 遍历
equations
和values
中的每一项,提取(s, e)
和对应的v
- 初始 s、e 的邻节点的哈希表
- 根据当前遍历到的
equation
填充 s、e 的邻节点的哈希表【构建4条边】![]()
- 步骤二⭐搜索图:广度优先搜索
- 初始化用于广度优先搜索的队列
queue
- 队列中的每一项为 🍅 搜索过的节点及对到 该节点所得到的权重积
mul
- 初始化结果答案列表
ans
:初始都为-1
表示未定义- 遍历
queries
中的每一项:寻找从起点到终点的最短路径,并计算权重积
class Solution:
def calcEquation(self, equations: List[List[str]], values: List[float], queries: List[List[str]]) -> List[float]:
# ---------------------------------------------------------- step 1
graph = {}
for (s, e), v in zip(equations, values): # --------------- step 1.1
# ----------------------------------------------------- step 1.2
if s not in graph:
graph[s] = {} # 初始 s 的邻节点的哈希表
if e not in graph:
graph[e] = {} # 初始 e 的邻节点的哈希表
# ----------------------------------------------------- step 1.3
graph[s][e] = v # s -> e, 权重为 v, 表示 s / e = v
graph[e][s] = 1 / v # e -> s, 权重为 1/v, 表示 e / s = 1/v
graph[s][s] = 1.0 # s -> s, 权重为 1, 表示 s / s = 1
graph[e][e] = 1.0 # e -> e, 权重为 1, 表示 e / e = 1
# ---------------------------------------------------------- step 2
queue = [] # -------------------------------------------- step 2.1
ans = [-1.0] * len(queries) # --------------------------- step 2.2
# -------------------------------------------------------- step 2.3
for i, (qx, qy) in enumerate(queries):
if qx not in graph or qy not in graph: continue # 未出现的变量,跳过
queue = [[qx, 1.0]] # 初始将起点节点入队
visited = set() # 已处理节点
while queue:
# 获取当前处理的节点 node 以及到该节点所得到的权重积mul
node, mul = queue.pop(0)
visited.add(node)
for neighbor, weight in graph[node].items(): # 枚举该节点的所有邻节点
if neighbor == qy:
ans[i] = mul * weight # 找到终点,更新权重积后存储到答案并退出查找
break
if neighbor not in visited: # 找到一个未处理的邻节点加入队列
queue.append([neighbor, mul * weight]) # 将未处理的邻节点及到达该节点时的权重积加入队列
return ans
希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦
🔥 LeetCode 热题 HOT 100