LeetCode 399 Evaluate Division(BFS)

来源:互联网 发布:英语短语软件 编辑:程序博客网 时间:2024/06/08 16:23

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.

题目大意:给出一些形如A / B = k的等式,其中A和B都是字符串,k是浮点数。然后给出一些未知的查询,返回查询结果;如果结果不存在,返回-1。

例如:

给出a / b = 2.0, b / c = 3.0.

查询有a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?.

返回结果是[6.0, 0.5, -1.0, 1.0, -1.0].

解题思路:

对于A / B = k,把A和B看成图上的节点,k则是由节点A指向节点B的一条有向边上的权值;1/k则是由B指向A的一条有向边上的权值。按照这个关系建图,然后根据查询遍历图中的节点,DFS、BFS和双向BFS都可以。注意因为A和B都是字符串,所以要把他们映射成整型数再建图。

代码如下:

const int maxn = 1000;struct Edge {    int from, to;    double cost;    Edge(int u, int v, double d):from(u), to(v), cost(d){}};class Solution {public:    void addEdge(int from, int to, double cost) {        edges.push_back(Edge(from, to, cost));        G[from].push_back(edges.size()-1);    }        double bfs(int from, int to) {        queue<pair<int, double>> que;        que.push(make_pair(from, 1));        vis[from] = true;        while(que.size()){            pair<int, double> p = que.front();            que.pop();            if(p.first == to) return p.second;            for(int i = 0;i < G[p.first].size();i++){                Edge e = edges[G[p.first][i]];                if(vis[e.to]) continue;                que.push(make_pair(e.to, p.second * e.cost));                vis[e.to] = true;            }        }        return -1;    }        vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values,                                vector<pair<string, string>> queries) {        for(int i = 0, j = 1;i < equations.size();i++) {            pair<string, string> p = equations[i];                        if(!id[p.first])id[p.first] = j++;            if(!id[p.second])id[p.second] = j++;                        addEdge(id[p.first], id[p.second], values[i]);            addEdge(id[p.second], id[p.first], 1.0/values[i]);        }                vector<double> ans;        for(int i = 0; i < queries.size();i++) {            pair<string, string> p = queries[i];            if(id[p.first] && id[p.second]){                memset(vis, 0, sizeof(vis));                double d = bfs(id[p.first], id[p.second]);                ans.push_back(d);            }else {                ans.push_back(-1);            }        }        return ans;    }private:    unordered_map<string, int> id;    vector<Edge> edges;    vector<int> G[maxn];    bool vis[maxn];};