题目
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 ].
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 ].
翻译
给定一组除法的等式,格式为A/B = k。A和B使用字符串表示的一个变量。
然后假设有一组查询。请你返回结果。如果结果不存在,则返回-1.0
思路详解
刚开始的时候没有思路,然后看了leetcode的提示之后,意识到该题应该抽象成一个图论的问题。
思路如下:
首先a/b = 2.0,就可以看做从a->b,距离为2.0。同时因为从a能到b,那么也可以从b到a。即b/a = 1/2.0 = 0.5。
那么就可以将所有的除法式子转换成有向图。
如果要就算a/b,那就就从图中找从a到b是否可达,统计记录距离,这里距离需要乘。
因为a/b,b/c。那么a/c = (a/b)*(b/c)。
代码
struct Arc{
string node;
double len;
Arc(string n,double l){
node = n;
len = l;
}
};
class Solution {
public:
//判断是否都应被访问
bool isAllVisited(vector<Arc> &arcs,map<string,bool> &visited){
for(int i = 0; i < arcs.size(); i ++){
if(visited[arcs[i].node] == false){
return false;
}
}
return false;
}
double dfs(string start,string end,map<string,vector<Arc> > &graph,map<string,bool> &visited,double l){
double result = -1.0;
if(start == end){
result = l;
return l;
}else{
vector<Arc> all_arc = graph[start];
//如果从该点出发,所有目标点都被访问,则退出
if(isAllVisited(all_arc,visited)){
}else{
for(int i = 0; i < all_arc.size();i++){
//判断是否已被访问,如果没有被访问,则进行深度遍历
if(visited[all_arc[i].node] == false){
visited[all_arc[i].node] = true; //标记已被访问
double t = dfs(all_arc[i].node,end,graph,visited,l*all_arc[i].len);
if(t != -1.0){
result = t;
break;
}
}
}
}
}
return result;
}
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
vector<double> res;
map<string,vector<Arc> > graph;
map<string,bool> visit;
//构造邻接表
for(int i = 0; i < equations.size(); i++){
graph[equations[i].first].push_back(Arc(equations[i].second,values[i]));
graph[equations[i].second].push_back(Arc(equations[i].first,1/values[i]));
visit[equations[i].first] = false;
visit[equations[i].second] = false;
}
//查询
for(int i = 0; i < queries.size();i ++){
if(visit.count(queries[i].first) == 0 || visit.count(queries[i].second) == 0){
res.push_back(-1.0);
}else{
//遍历起点queries[i].first -> queries[i].second ,求距离
map<string,bool> visited;
double t_res = dfs(queries[i].first,queries[i].second,graph,visited,1.0);
res.push_back(t_res);
}
}
return res;
}
};
总结
1,问题抽象很重要。如何看待问题,从什么角度看待问题,决定解决问题的方式。