【算法】【Graph】Evaluate Division

来源:互联网 发布:手机不能使用4g网络 编辑:程序博客网 时间:2024/05/14 13:45

Difficulty:Medium

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.

Solution

思路

构建一个有向图(加权图),equations中的每个分母和分子都是一个节点,边则是它们相除的值。例如,a / b = 2.0表示a指向b的边为2.0b指向a的边为0.5.

代码

通过Leetcode测试,速度快过75%左右的人。

class Solution {public:    vector<double> calcEquation(vector<pair<string, string>> equations,         vector<double>& values, vector<pair<string, string>> queries) {        vector<double> result;   // 返回的结果        result.resize(queries.size());        string f, s;        // 构造有向图        for (int i = 0; i < equations.size(); ++i) {            f = equations[i].first;            s = equations[i].second;            graph[f][s] = values[i];            graph[s][f] = 1.0 / values[i];        }        double temp;        for (int i = 0; i < queries.size(); ++i) {            unordered_set<string> visited;            temp = dfs(queries[i].first, queries[i].second, visited);            result[i] = (temp == 0.0) ? -1.0 : temp;        }        return result;    }private:    unordered_map<string, unordered_map<string, double>> graph;    double dfs(string src, string dst, unordered_set<string>& visited) {        for (pair<string, double> v : graph[src]) {   // 拓展子节点            if (visited.find(v.first) == visited.end()) {                if (v.first == dst) return v.second;  // 找到目标节点,返回                visited.insert(v.first);                double temp = dfs(v.first, dst, visited);                if (temp != 0) return v.second * temp;   // 说明上面的dfs找到了目标,可以返回                                                         // 否则继续拓展子节点            }        }        return 0.0;    // 找不到目标,该query无解    }};
原创粉丝点击