399.除法求值
给你一个变量对数组 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 ]
示例 2:
输入:equations = [["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0], queries = [["a","c"],["c","b"],["bc","cd"],["cd","bc"]] 输出:[3.75000,0.40000,5.00000,0.20000]
示例 3:
输入:equations = [["a","b"]], values = [0.5], queries = [["a","b"],["b","a"],["a","c"],["x","y"]] 输出:[0.50000,2.00000,-1.00000,-1.00000]
提示:
1 <= equations.length <= 20
equations[i].length == 2
1 <= Ai.length, Bi.length <= 5
values.length == equations.length
0.0 < values[i] <= 20.0
1 <= queries.length <= 20
queries[i].length == 2
1 <= Cj.length, Dj.length <= 5
Ai, Bi, Cj, Dj
由小写英文字母与数字组成
方法一:bfs
时间复杂度:O(ML+Q·(L+M))
空间复杂度:O(NL+M)
1 /** 2 * @param {string[][]} equations 3 * @param {number[]} values 4 * @param {string[][]} queries 5 * @return {number[]} 6 */ 7 var calcEquation = function(equations, values, queries) { 8 let nvars = 0; 9 const variables = new Map(); 10 11 const n = equations.length; 12 for (let i = 0; i < n; i++) { 13 if (!variables.has(equations[i][0])) { 14 variables.set(equations[i][0], nvars++); 15 } 16 if (!variables.has(equations[i][1])) { 17 variables.set(equations[i][1], nvars++); 18 } 19 } 20 21 // 对于每个点,存储其直接连接到的所有点及对应的权值 22 const edges = new Array(nvars).fill(0); 23 for (let i = 0; i < nvars; i++) { 24 edges[i] = []; 25 } 26 for (let i = 0; i < n; i++) { 27 const va = variables.get(equations[i][0]), vb = variables.get(equations[i][1]); 28 edges[va].push([vb, values[i]]); 29 edges[vb].push([va, 1.0 / values[i]]); 30 } 31 32 const queriesCount = queries.length; 33 const ret = []; 34 for (let i = 0; i < queriesCount; i++) { 35 const query = queries[i]; 36 let result = -1.0; 37 if (variables.has(query[0]) && variables.has(query[1])) { 38 const ia = variables.get(query[0]), ib = variables.get(query[1]); 39 if (ia === ib) { 40 result = 1.0; 41 } else { 42 const points = []; 43 points.push(ia); 44 const ratios = new Array(nvars).fill(-1.0); 45 ratios[ia] = 1.0; 46 47 while (points.length && ratios[ib] < 0) { 48 const x = points.pop(); 49 for (const [y, val] of edges[x]) { 50 if (ratios[y] < 0) { 51 ratios[y] = ratios[x] * val; 52 points.push(y); 53 } 54 } 55 } 56 result = ratios[ib]; 57 } 58 } 59 ret[i] = result; 60 } 61 return ret; 62 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理