/** * @param {string[][]} equations * @param {number[]} values * @param {string[][]} queries * @return {number[]} */ const calcEquation = function (equations, values, queries) { }; /* 思路:通过equations和values建立一张有权图edges:[[[1, 2],...], [[2, 3],...]],在这里使用邻接表的方式表示,edges表示的是0号顶点可以到一号顶点 并且权值为2,1顶点到2号顶点的权值是3,如果0号顶点表示a,1号顶点表示b,2号顶点表示c,那么这个图在这个题目里面的意思就是,a/b=2,b/c=2,如果要我们, 求a/c的值不就是把a->b->c这个路径里面的权值相乘吗?所以这个题目可以分为下面几步: 步骤: 1.通过equations,values建立有权图edges 2.遍历queries,比如要我们求a/e,那么我们就从a为起点出发,开始广度优先遍历,知道找到a->e的路径,之后加权(相乘),如果没找到,就是-1 */ function f1(equations, values, queries) { // Step 1: 给每个变量编号,变量名映射到编号 let nvars = 0; // 变量的数量 const variables = new Map(); // 存储变量名到编号的映射 // 处理 equations,给每个变量一个唯一的编号 const n = equations.length; for (let i = 0; i < n; i++) { // 如果变量没有编号,就给它一个编号 if (!variables.has(equations[i][0])) { variables.set(equations[i][0], nvars++); } if (!variables.has(equations[i][1])) { variables.set(equations[i][1], nvars++); } } // Step 2: 创建图结构,存储每个节点与其他节点的比值 const edges = new Array(nvars).fill(0); // 创建一个数组来存储每个节点的邻接点和比值 for (let i = 0; i < nvars; i++) { edges[i] = []; // 初始化每个节点的邻接表 } // 遍历 equations,构建图,每条边的权值是它们之间的比值 for (let i = 0; i < n; i++) { const va = variables.get(equations[i][0]); // 获取变量 a 的编号 const vb = variables.get(equations[i][1]); // 获取变量 b 的编号 edges[va].push([vb, values[i]]); // a → b 的比值 edges[vb].push([va, 1.0 / values[i]]); // b → a 的比值是 1 / (a → b) } // Step 3: 处理查询,计算每个查询的结果 const queriesCount = queries.length; // 查询的数量 const ret = []; // 存储每个查询的结果 for (let i = 0; i < queriesCount; i++) { const query = queries[i]; // 当前查询 let result = -1.0; // 默认结果为 -1.0,表示无法计算 // 只有当查询中的两个变量都存在时,才进行计算 if (variables.has(query[0]) && variables.has(query[1])) { const ia = variables.get(query[0]); // 获取查询中第一个变量的编号 const ib = variables.get(query[1]); // 获取查询中第二个变量的编号 // 如果两个变量是同一个,直接返回 1.0 if (ia === ib) { result = 1.0; } else { // Step 4: 使用 DFS 或 BFS 遍历图,查找从 ia 到 ib 的比值 const points = []; // 存储当前正在遍历的节点 points.push(ia); // 从 ia 开始遍历 const ratios = new Array(nvars).fill(-1.0); // 存储每个节点的比值,初始值为 -1.0,表示不可达 ratios[ia] = 1.0; // 起点 ia 到 ia 的比值是 1.0 // 使用 DFS 方式遍历图 while (points.length && ratios[ib] < 0) { const x = points.pop(); // 从栈中取出一个节点 // 遍历当前节点的所有邻接点 for (const [y, val] of edges[x]) { // 如果邻接点 y 尚未访问过(ratios[y] < 0) if (ratios[y] < 0) { ratios[y] = ratios[x] * val; // 更新 y 的比值 points.push(y); // 将 y 加入栈中继续遍历 } } } result = ratios[ib]; // 查询的结果是 ib 到达的比值 } } // 将当前查询的结果存入结果数组 ret[i] = result; } // 返回所有查询的结果 return ret; }