LeetCode OJ 399. Evaluate Division
Description
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.
解题思路
比较直观的思路就是图的深度优先搜索,字符串可以看做是树上的一个节点,两个字符串之间的商可以看做是从一个节点到另一个节点之间的距离。这样,对于queries就是查询树上两个节点的距离,如果节点不在树上,则距离为-1.0,节点到自身的距离为1.0。使用map将字符串与整数下标进行映射,使用二维数组存储图,其中每一行表示某一节点的邻接信息(使用pair存储邻接节点和距离),使用队列对树进行深搜。visit数组记录节点的访问信息。
DFS过程:对于字符串(a,b)的距离,我们从节点a开始,a入队。当队列不为空,队首元素top出队,搜索top的邻接节点,并根据图存储的信息更新top与邻接节点的距离,同时把top的邻接节点放到队列中。循环直到找到b节点,此时的距离就是a到b的距离。
代码
class Solution {
public:
double dfs(vector<vector<pair<int, double> > >& graph, int a, int b){
int size = graph.size();
vector<double> dist(size, 1.0);
queue<int> q;
q.push(a);
vector<int> visit(size, 0);
while(!q.empty()){
int tmp = q.front();
cout << "tmp1:" << tmp << endl;
q.pop();
cout << "graph[tmp].size()" << graph[tmp].size() << endl;
for(int i = 0; i < graph[tmp].size(); i++){
int next = graph[tmp][i].first;
double value = graph[tmp][i].second;
if(visit[next])
continue;
cout << "tmp2:" << tmp << endl;
dist[next] = dist[tmp] * value;
cout << "tmp:" << dist[tmp] << endl;
cout << next << tmp << ' ' << dist[next] << endl;
if(next == b)
return dist[next];
visit[next] = 1;
q.push(next);
}
}
return -1.0;
}
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
vector<double> ans;
vector<vector<pair<int, double> > > graph; //每一行存的是一个节点的所有邻接节点和距离
map<string, int> m; //存储字符串和整数的对应关系
for(int i = 0; i < equations.size(); i++){
string x = equations[i].first;
string y = equations[i].second;
if(m.count(x) == 0){
m[x] = graph.size();
vector<pair<int,double> > v;
graph.push_back(v);
}
if(m.count(y) == 0){
m[y] = graph.size();
vector<pair<int,double> > v;
graph.push_back(v);
}
int a = m[x], b = m[y];
graph[a].push_back(pair<int, double>(b, values[i]));
//cout << graph[a][graph[a].size() - 1].second << endl;
graph[b].push_back(pair<int, double>(a, 1.0 / values[i]));
//cout << graph[b][graph[b].size() - 1].second << endl;
}
for(int i = 0; i < queries.size(); i++){
string x = queries[i].first;
string y = queries[i].second;
if(m.count(x) == 0 || m.count(y) == 0)
ans.push_back(-1.0);
else if(x == y)
ans.push_back(1.0);
else{
int a = m[x], b = m[y];
//cout << "a:" << a << " b:" << b << endl;
ans.push_back(dfs(graph, a, b));
}
}
return ans;
}
};