97 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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号顶点可以到一号顶点
并且权值为21顶点到2号顶点的权值是3如果0号顶点表示a,1号顶点表示b,2号顶点表示c那么这个图在这个题目里面的意思就是a/b=2,b/c=2,如果要我们,
求a/c的值不就是把a->b->c这个路径里面的权值相乘吗所以这个题目可以分为下面几步
步骤:
1.通过equationsvalues建立有权图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;
}