Equations are given in the format A / B = k
, where A
and B
are variables represented as strings, and k
is a real number (floating point number). Given some queries, return the answers. If the answer does not exist, return -1.0
.
Example:
Given a / b = 2.0, b / c = 3.0.
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
return [6.0, 0.5, -1.0, 1.0, -1.0 ].
The input is: vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries
, where equations.size() == values.size()
, and the values are positive. This represents the equations. Return vector<double>
.
equations = [ ["a", "b"], ["b", "c"] ], values = [2.0, 3.0], queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ].
已知a/b, b/c ...的值, 估计a/c , b/a...的值。
用图的方法解决,a/b的值就是a->b的路径的权重,那么要估计a->c的值,就是求a->c的路径。
解决:
1、为输入创建一个表table,存放权重,为了索引方便,为每个节点匹配一个索引值index。
2、对于每个要估计的式子 x1/x2:
2.1、如果x1->x2路径存在,直接输出。
2.2、如果求x1->x2不存在,找到一个未访问过的点xj,使得x1->xj路径存在,求xj->x2的路径。
那么findPath(x1, x2) = findPath(x1, xj) * findPath(xj, x2);
2.3、更新table并输出。
1 class Solution { 2 public: 3 double findPath(vector<vector<double>> &table, vector<int> &visited, int start, int target) { 4 double res = -1.0; 5 for (int i=0; i<table.size(); ++i) { 6 if (table[start][target] > 0.0) 7 break; 8 if (i == start) 9 continue; 10 if (table[start][i] > 0.0 && visited[i] == 0) { 11 visited[i] = 1; 12 res = table[start][i] * findPath(table, visited, i, target); 13 visited[i] = 0; 14 table[start][target] = res > 0.0? res: -1.0; 15 } 16 } 17 return table[start][target]; 18 } 19 vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) { 20 int len = equations.size(); 21 unordered_map<string, int> index; 22 int i = 0; 23 for (auto &equ : equations) { 24 if (index.find(equ.first) == index.end()) 25 index[equ.first] = i++; 26 if (index.find(equ.second) == index.end()) 27 index[equ.second] = i++; 28 } 29 vector<vector<double>> table(i, vector<double>(i, -1.0)); 30 while (--i >= 0) table[i][i] = 1.0; 31 for (i=0; i<len; ++i) { 32 pair<string, string> equ = equations[i]; 33 table[index[equ.first]][index[equ.second]] = values[i]; 34 table[index[equ.second]][index[equ.first]] = 1.0 / values[i]; 35 } 36 vector<double> res; 37 for (auto &qur : queries) { 38 string start = qur.first; 39 string target = qur.second; 40 vector<int> visited(table.size()); 41 if (index.find(start)==index.end() || index.find(target)==index.end()) 42 res.push_back(-1.0); 43 else { 44 visited[i] = 1; 45 res.push_back(findPath(table, visited, index[start], index[target])); 46 visited[i] = 0; 47 } 48 } 49 return res; 50 } 51 };