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;
}
};