输入: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
//C++ class Solution { public: vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) { int nvars = 0; unordered_map<string, int> variables;
int n = equations.size(); for (int i = 0; i < n; i++) { if (variables.find(equations[i][0]) == variables.end()) { variables[equations[i][0]] = nvars++; } if (variables.find(equations[i][1]) == variables.end()) { variables[equations[i][1]] = nvars++; } }
// 对于每个点,存储其直接连接到的所有点及对应的权值 vector<vector<pair<int, double>>> edges(nvars); for (int i = 0; i < n; i++) { int va = variables[equations[i][0]], vb = variables[equations[i][1]]; edges[va].push_back(make_pair(vb, values[i])); edges[vb].push_back(make_pair(va, 1.0 / values[i])); }
vector<double> ret; for (const auto& q: queries) { double result = -1.0; if (variables.find(q[0]) != variables.end() && variables.find(q[1]) != variables.end()) { int ia = variables[q[0]], ib = variables[q[1]]; if (ia == ib) { result = 1.0; } else { queue<int> points; points.push(ia); vector<double> ratios(nvars, -1.0); ratios[ia] = 1.0;
while (!points.empty() && ratios[ib] < 0) { int x = points.front(); points.pop();
for (const auto [y, val]: edges[x]) { if (ratios[y] < 0) { ratios[y] = ratios[x] * val; points.push(y); } } } result = ratios[ib]; } } ret.push_back(result); } return ret; } };
//Java class Solution { public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) { int nvars = 0; Map<String, Integer> variables = new HashMap<String, Integer>();
int n = equations.size(); for (int i = 0; i < n; i++) { if (!variables.containsKey(equations.get(i).get(0))) { variables.put(equations.get(i).get(0), nvars++); } if (!variables.containsKey(equations.get(i).get(1))) { variables.put(equations.get(i).get(1), nvars++); } }
// 对于每个点,存储其直接连接到的所有点及对应的权值 List<Pair>[] edges = new List[nvars]; for (int i = 0; i < nvars; i++) { edges[i] = new ArrayList<Pair>(); } for (int i = 0; i < n; i++) { int va = variables.get(equations.get(i).get(0)), vb = variables.get(equations.get(i).get(1)); edges[va].add(new Pair(vb, values[i])); edges[vb].add(new Pair(va, 1.0 / values[i])); }
int queriesCount = queries.size(); double[] ret = new double[queriesCount]; for (int i = 0; i < queriesCount; i++) { List<String> query = queries.get(i); double result = -1.0; if (variables.containsKey(query.get(0)) && variables.containsKey(query.get(1))) { int ia = variables.get(query.get(0)), ib = variables.get(query.get(1)); if (ia == ib) { result = 1.0; } else { Queue<Integer> points = new LinkedList<Integer>(); points.offer(ia); double[] ratios = new double[nvars]; Arrays.fill(ratios, -1.0); ratios[ia] = 1.0;
while (!points.isEmpty() && ratios[ib] < 0) { int x = points.poll(); for (Pair pair : edges[x]) { int y = pair.index; double val = pair.value; if (ratios[y] < 0) { ratios[y] = ratios[x] * val; points.offer(y); } } } result = ratios[ib]; } } ret[i] = result; } return ret; } }