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

48 篇文章 0 订阅
1 篇文章 0 订阅

题目

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值