首页 > 代码库 > 399. Evaluate Division

399. Evaluate Division

 

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.

The idea comes from the following:

A variation of Floyd–Warshall, computing quotients instead of shortest paths. An equation A/B=k is like a graph edge A->B, and(A/B)*(B/C)*(C/D) is like the path A->B->C->D. Submitted once, accepted in 35 ms.

https://discuss.leetcode.com/topic/58482/9-lines-floyd-warshall-in-python

but implemented in C++.

class Solution {
public:
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
        unordered_map<string, double> edge_weight_hash;
        unordered_set<string> vertices;
        for(int i = 0; i < equations.size(); i++){
            string a = equations[i].first;
            string b = equations[i].second;
            double val = values[i];
            if(val == 0) continue;
            edge_weight_hash[a+"_"+a] = 1.0;
            edge_weight_hash[b+"_"+b] = 1.0;
            edge_weight_hash[a+"_"+b] = val;
            edge_weight_hash[b+"_"+a] = 1/val;
            vertices.insert(a);
            vertices.insert(b);
        }
        auto ss = vertices.begin();
        auto se = vertices.end();
        auto hend = edge_weight_hash.end();
        for(auto kit = ss; kit != se; ++kit){
            for(auto iit = ss; iit != se; ++iit){
                for(auto jit = ss; jit !=se; ++jit){
                    string i = *iit;
                    string j = *jit;
                    string k = *kit;
                    if(edge_weight_hash.find(i+"_"+k) == hend || edge_weight_hash.find(k+"_"+j) == hend) continue;
                    double new_val = edge_weight_hash[i+"_"+k] * edge_weight_hash[k+"_"+j];
                    //if(edge_weight_hash.find(i+"_"+j) != hend){
                    //    edge_weight_hash[i+"_"+j] = min(edge_weight_hash[i+"_"+j], new_val);
                    //}else{
                        edge_weight_hash[i+"_"+j] = new_val;
                    //}
                }
            }
        }
        vector<double> results;
        for(auto q: queries){
            string key = q.first+"_"+q.second;
            results.push_back(edge_weight_hash.find(key) != hend ? edge_weight_hash[key] : -1); 
        }
        return results;
    }
};

 

399. Evaluate Division