LeetCode-399. Evaluate Division-思路详解-C++

来源:互联网 发布:java设计模式有几种 编辑:程序博客网 时间:2024/06/06 00:10

题目

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,问题抽象很重要。如何看待问题,从什么角度看待问题,决定解决问题的方式。

0 0