399. Evaluate Division

问题描述:

Equations are given in the format A / B = k, where Aand 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.

解题思路:

给出已知算式{E1, E2.......En},通过使用已知算式进行运算得到问题算式{Q1, Q2........Qk}的结果,若无法通过当前算式得到结果则返回-1.0

可以将已知算式 {Ek | k belongs to 1....n}  构建成图,操作数作为顶点,结果作为边的权重。

由于可能会出现a/b和b/a两种情况,我们使用有向图来表示算式,边从被除数指向除数:

    即 若 算式为 a/b = 2.0 

    可有图  a-----2.0----->b

我们使用邻接矩阵来表示有向图。

对于操作数:并不能确定会有什么操作数出现,而我们又需要构建邻接矩阵,所以我们需要一个索引映射(idxMap),将操作符映射到唯一一个索引。

在得到idxMap后我们可以构建图:

  对每一个算式 a/b = 2.0, 需要更新 graph[a][a] = 1.0, graph[b][b] = 1.0, graph[a][b] = 2.0, graph[b][a] = 1.0/2.0

得到图后,我们从所求算式的被除数开始进行dfs。

注意需要visited来保证不出现环(即重复检测)

代码:

class Solution {
public:
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
        vector<double> res;
        if(queries.empty()) return res;
        
        //if equations is empty
        if(equations.empty()){
            for(int i = 0; i < queries.size(); i++){
                res.push_back(-1.0);
            }
            return res;
        }
        //init graph
        unordered_map<string, int> idxMap;
        //init the index mapping
        for(auto e : equations){
            if(idxMap.count(e.first) == 0)  
                idxMap[e.first] = idxMap.size();
            if(idxMap.count(e.second) == 0)
                idxMap[e.second] = idxMap.size();
        }
        std::cout<<idxMap.size()<<std::endl;
        //init the graph
        vector<vector<double>> g(idxMap.size(), vector<double>(idxMap.size(), -1.0));
        for(int i = 0; i < equations.size(); i++){
            int dividend = idxMap[equations[i].first];
            int divisor = idxMap[equations[i].second];
            
            g[dividend][divisor] = values[i];
            g[dividend][dividend] = 1.0;
            g[divisor][divisor] = 1.0;
            g[divisor][dividend] = 1.0/values[i];
        }
        
        for(auto q : queries){
            res.push_back(calculateQuery(q, g, idxMap));
        }
        return res;
    }
private:
    double dfs(vector<vector<double>> &graph, vector<bool> &visited, 
               int idx, int targetIdx){
        
        for(int i = 0; i < visited.size(); i++){
            if(i == idx) {
                visited[i] = true;
                continue;
            }
            if(graph[idx][i] != -1.0){
                if(i == targetIdx){
                    return graph[idx][targetIdx];
                }
                if(!visited[i]){
                    visited[i] == true;
                    double res = dfs(graph, visited, i, targetIdx);
                    if(res != -1){
                        return graph[idx][i] * res;
                    }
                }
            }
        }
        return -1.0;
    }
    double calculateQuery(pair<string, string> &q, 
                          vector<vector<double>> &graph,
                          unordered_map<string, int> &idxMap){
        int idx, targetIdx;
        if(idxMap.count(q.first) == 0) return -1.0;
        else idx = idxMap[q.first];
        if(idxMap.count(q.second) == 0) return -1.0;
        else targetIdx = idxMap[q.second];
        if(q.first == q.second) return 1.0;
        vector<bool> visited(idxMap.size(), false);
        return dfs(graph, visited, idx, targetIdx);
    }
    
    
};
原文地址:https://www.cnblogs.com/yaoyudadudu/p/10728867.html