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>
.
According to the example above:
equations = [ ["a", "b"], ["b", "c"] ], values = [2.0, 3.0], queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ].
The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.
题目大意:给出一些形如A / B = k的等式,其中A和B都是字符串,k是浮点数。然后给出一些未知的查询,返回查询结果;如果结果不存在,返回-1。例如:
给出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].
解题思路:
对于A / B = k,把A和B看成图上的节点,k则是由节点A指向节点B的一条有向边上的权值;1/k则是由B指向A的一条有向边上的权值。按照这个关系建图,然后根据查询遍历图中的节点,DFS、BFS和双向BFS都可以。注意因为A和B都是字符串,所以要把他们映射成整型数再建图。
代码如下:
const int maxn = 1000;
struct Edge {
int from, to;
double cost;
Edge(int u, int v, double d):from(u), to(v), cost(d){}
};
class Solution {
public:
void addEdge(int from, int to, double cost) {
edges.push_back(Edge(from, to, cost));
G[from].push_back(edges.size()-1);
}
double bfs(int from, int to) {
queue<pair<int, double>> que;
que.push(make_pair(from, 1));
vis[from] = true;
while(que.size()){
pair<int, double> p = que.front();
que.pop();
if(p.first == to) return p.second;
for(int i = 0;i < G[p.first].size();i++){
Edge e = edges[G[p.first][i]];
if(vis[e.to]) continue;
que.push(make_pair(e.to, p.second * e.cost));
vis[e.to] = true;
}
}
return -1;
}
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values,
vector<pair<string, string>> queries) {
for(int i = 0, j = 1;i < equations.size();i++) {
pair<string, string> p = equations[i];
if(!id[p.first])id[p.first] = j++;
if(!id[p.second])id[p.second] = j++;
addEdge(id[p.first], id[p.second], values[i]);
addEdge(id[p.second], id[p.first], 1.0/values[i]);
}
vector<double> ans;
for(int i = 0; i < queries.size();i++) {
pair<string, string> p = queries[i];
if(id[p.first] && id[p.second]){
memset(vis, 0, sizeof(vis));
double d = bfs(id[p.first], id[p.second]);
ans.push_back(d);
}else {
ans.push_back(-1);
}
}
return ans;
}
private:
unordered_map<string, int> id;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
};