Leetcode算法學習日誌-399 Evaluate Division

Leetcode 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.

題意分析

給出多個觸發等式作爲已知條件,判斷是否能得到目標計算的結果,如果能,返回結果,不能,返回-1.0.對於分子分母相等的目標計算式,如果運算元素在已知條件等式中,則返回結果1,不然結果仍爲-1.0.分子分母都是由string表示的一個數。

解法分析

當目標計算式就在已知條件中時可以直接得到結果,如果不在其中,需要判斷經過多次相乘,能否得到最終結果,由於a/b=2.0,同時可得b/a=0.5,加入目標爲a/c,則該問題可以看做a和c之間的尋路問題,a->b的權重爲2.0,b->a的權重爲0.5.因此可以利用已知等式構造一個圖,從起點a開始尋路到c,利用深度優先搜索,遍歷a的相鄰點,並延某一點一直往下走,注意走過的點要用attended進行記錄。

由本題可以看到,BFS和DFS的運用最主要是將問題轉化爲一個圖問題,樹的遍歷只是一個特例。C++代碼如下:

class Solution {
private:
    double value;
    string b;
    unordered_map<string, vector<pair<string,double>>> myGraph;
    unordered_set<string> attended;
public:
    double findWay(string a){
        double res;
        if(attended.count(a))
            return -1.0;
        attended.insert(a);
        for(auto p:myGraph[a]){
            value*=p.second;
            if(p.first==b)
                return value;
            res=findWay(p.first);
            if(res==-1.0)
                value/=p.second;
            else
                return res;
            
        }
        return -1.0;
    }
    vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries){
        for(int i=0;i<values.size();i++){
            myGraph[equations[i].first].push_back(make_pair(equations[i].second,values[i]));
            myGraph[equations[i].second].push_back(make_pair(equations[i].first,1.0/values[i]));//make the graph
        }
        vector<double> res;
        for(auto q:queries){
            b=q.second;
            value=1;
            attended.clear();
            if(myGraph.count(q.first)==0||myGraph.count(q.second)==0)
                res.push_back(-1.0);
            else{
                if(q.first==q.second)
                    res.push_back(1.0);
                else
                    res.push_back(findWay(q.first));
            }   
        }
        return res; 
    }
};
代碼中用unordered_map<string,vector<pair<string,double>>>作爲表示本圖的數據結構,string作爲關鍵字,對應一個vector,vector元素爲pair,存儲與關鍵字相鄰(已知條件中分母)的string,以及他們的商。用unordered_set<string>來標記到過的節點,關聯容器STL s.count(x)返回關鍵字x出現的次數,對於本題用到的關聯容器,關鍵字不能重複出現,因此返回值爲0、1。




發佈了79 篇原創文章 · 獲贊 16 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章