Leetcode 399. Evaluate Division

Posted haoweizh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode 399. Evaluate Division相关的知识,希望对你有一定的参考价值。

Problem:

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:

  这道题感觉是Medium中难度比较大的题了。这道题可以用两种解法。第一种使用DFS,用一个哈希表记录string之间的比例关系,用used记录是否访问过该字符串,常规DFS即可。第二种用Union Find就比较复杂了,如果是面试则不推荐这种写法,比较费时间。和一般的Union Find不同的地方在于,parent这个哈希表需要额外记录并更新字符串之间的权重,x->{y,value}的含义是x/y=value。所以在进行Union函数时,x/px = weightx,y/py = weighty,x/y = value,因此根据rank可以得到px/py或py/px的值并对parent进行更新,这一步很容易出错,除数与被除数之间的关系容易搞反。所以正常情况下推荐DFS做法,不过从时间复杂度的角度分析,Unioni Find解法的效率要更高,因为对于每个query,他只需要进行两次Find函数即可,而相比之下DFS的解法最坏情况下需要遍历所有节点。

Code:

 

 1 class Solution {
 2 public:
 3     double func(unordered_map<string,vector<pair<double,string>>> &um,unordered_map<string,bool> &used,pair<string,string> query){
 4         for(int i = 0;i != um[query.first].size();++i){
 5             if(!used[um[query.first][i].second]){
 6                 if(um[query.first][i].second.compare(query.second) == 0){
 7                     return um[query.first][i].first;
 8                 }
 9                 else{
10                     used[query.first] = true;
11                     double t = func(um,used,make_pair(um[query.first][i].second,query.second));
12                     used[query.first] = false;
13                     if(t != -1)
14                         return um[query.first][i].first * t;
15                 }
16             }
17         }
18         return -1;
19     }
20     vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
21         unordered_map<string,vector<pair<double,string>>> um;
22         unordered_map<string,bool> used;
23         for(int i = 0;i != equations.size();++i){
24             um[equations[i].first].push_back(make_pair(values[i],equations[i].second));
25             um[equations[i].second].push_back(make_pair(1/values[i],equations[i].first));
26             used[equations[i].first] = false;
27             used[equations[i].second] = false;
28         }
29         vector<double> result;
30         for(int i = 0;i != queries.size();++i){
31             if(queries[i].first.compare(queries[i].second) == 0 && used.find(queries[i].first) != used.end())
32                 result.push_back(1.0);
33             else
34                 result.push_back(func(um,used,queries[i]));
35         }
36         return result;
37     }
38 };

 

 1 class Solution {
 2 public:
 3     string Find(unordered_map<string,pair<string,double>> &parent,string &target,double &weight){
 4         if(target == parent[target].first)
 5             return target;
 6         weight *= parent[target].second;
 7         return Find(parent,parent[target].first,weight);
 8     }
 9     bool Union(unordered_map<string,pair<string,double>> &parent,unordered_map<string,int> &rank,string &x,string &y,double &value){
10         double weightx = 1.0;
11         double weighty = 1.0;
12         string px = Find(parent,x,weightx);
13         string py = Find(parent,y,weighty);
14         if(px == py) return false;
15         if(rank[px] > rank[py]) {
16             parent[py].first = px;
17             parent[py].second = weightx/weighty/value;
18         }
19         else if(rank[px] < rank[py]) {
20             parent[px].first = py;
21             parent[px].second = weighty/weightx*value;
22         }
23         else{
24             parent[py].first = px;
25             parent[py].second = weightx/weighty/value;
26             rank[px]++;
27         }
28         return true;
29     }
30     vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
31         unordered_map<string,pair<string,double>> parent;
32         unordered_map<string,int> rank;
33         for(int i = 0;i != equations.size();++i){
34             parent[equations[i].first] = make_pair(equations[i].first,1.0);
35             parent[equations[i].second] = make_pair(equations[i].second,1.0);
36             rank[equations[i].first] = 0;
37             rank[equations[i].second] = 0;
38         }
39         for(int i = 0;i != equations.size();++i){
40             Union(parent,rank,equations[i].first,equations[i].second,values[i]);
41         }
42         vector<double> result;
43         for(int i = 0;i != queries.size();++i){
44             if(parent.find(queries[i].first) != parent.end() && parent.find(queries[i].second) != parent.end()){
45                 double weightx = 1.0;
46                 double weighty = 1.0;
47                 string px = Find(parent,queries[i].first,weightx);
48                 string py = Find(parent,queries[i].second,weighty);
49                 if(px != py) result.push_back(-1.0);
50                 else
51                     result.push_back(weightx/weighty);
52             }
53             else
54                 result.push_back(-1.0);
55         }
56         return result;
57     }
58 };

 




以上是关于Leetcode 399. Evaluate Division的主要内容,如果未能解决你的问题,请参考以下文章

leetcode [399]Evaluate Division

[LeetCode] 399. Evaluate Division Java

[leetcode]Graph-399. Evaluate Division

[LeetCode] 399. Evaluate Division 求除法表达式的值

399. Evaluate Division

399. Evaluate Division