leetcode Evaluate Division

EvaluateDivision

题目详情:

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.

解题方法:

看到这个题目时,不知道应该用什么数据结构来存储图。该开始想的使用map<pair<string, string>, double>,但是这样是不行的,没办法存储每个顶点对应的边。所以参考了discuss中的方法,使用unordered_map<string, unordered_map<string, double> > 来存储图。键值为顶点,每个顶点对应一个map这个map中存储了顶点对应的分母,以及顶点/分母得到的值,这个图是双向的,注意这里要判断,分子是否为0,顶点/分母是否为0。对于每个querie,graph[a].find(b) != graph[a].end() 即能找到以a为分子,b为分母的边,则将结果加入vector。如果找不到以a为分子,b为分母的边,则便利每个a的邻居,看是否能找到以a的邻居为分子,b为分母的边。这里要记录是否便利过某个顶点,没办法使用一个bool的数组来存储这个信息,这个维护一个set,如果便利过,则将其加入set。如过不再set中则没便利过。


代码详情:

class Solution {
public:
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
        unordered_map<string, unordered_map<string, double> > graph;
        vector<double> result;
        for (int i = 0; i < values.size(); i++) {
            graph[equations[i].first].insert(make_pair(equations[i].second, values[i]));
            if (values[i] != 0) {
                graph[equations[i].second].insert(make_pair(equations[i].first, 1 / values[i]));
            }
        }

        for (int i = 0; i < queries.size(); i++) {
            unordered_set<string> s; // to know whether a node is find or not
            double temp = calculate(queries[i].first, queries[i].second, graph, s);
            result.push_back(temp);
        }
        return result;
    }
    double calculate(string a, string b, unordered_map<string, unordered_map<string, double> >& graph, unordered_set<string>& s) {
        if (graph[a].find(b) != graph[a].end()) return graph[a][b];
        unordered_map<string, double>::iterator iter;
        for (iter = graph[a].begin(); iter != graph[a].end(); iter++) {  // calculate neibour of a to find b
            if (s.find((*iter).first) == s.end()) {
                s.insert((*iter).first);
                double temp = calculate((*iter).first, b, graph, s);
                if (temp != -1.0) return (*iter).second * temp;
            }
        }
        return -1.0;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_40085482/article/details/78722972
今日推荐