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