题目大意:给出一些除法式子,除数和被除数都是字符串形式的字母,商是浮点型实数,根据给出的信息求出提问中的值
分析:图论或者哈希表+dfs。
图论:将分子分母都当做图中的结点,商作为边权,然后只需要用floyd算法算出所求的两点之间是否有路径及路径权重即可。
dfs:首先将两个vector里面的数据读出来建立哈希表,string就是哈希map的key值,相应的记录着一对<除数,商>。然后dfs搜索出一条从被除数到除数的路径并计算出路径总权值即可。
代码:
方法一:图论
class Solution {
public:
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
unordered_map<string,unordered_map<string,double>> hash; //储存图
for(int i = 0;i < equations.size();i++){ //建图
hash[equations[i].first][equations[i].second] = values[i];
hash[equations[i].second][equations[i].first] = 1.0 / values[i];
}
for(auto e : hash){ //建图
hash[e.first][e.first] = 1.0;
}
for(auto mid : hash){ //floyd变形求是否存在路径及路径权值
for(auto start : hash){
for(auto end : hash){
if(hash[start.first].count(mid.first) && hash[mid.first].count(end.first))
hash[start.first][end.first] = hash[start.first][mid.first] * hash[mid.first][end.first];
}
}
}
vector<double> ans;
for(auto q : queries){
double value = -1.0;
if(hash[q.first].count(q.second)) value = hash[q.first][q.second];
ans.push_back(value);
}
return ans;
}
};
方法二:dfs转载自http://blog.csdn.net/u011934885/article/details/52510328
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> query) {
unordered_map<string, vector<pair<string, double>>> table;
vector<double> res;
for (int i = 0; i < equations.size(); i++) {
table[equations[i].first].push_back(make_pair(equations[i].second, values[i]));
table[equations[i].second].push_back(make_pair(equations[i].first, double(1.0f / values[i])));
}
for (int i = 0; i < query.size(); i++) {
unordered_set<string> visited;
visited.insert(query[i].first);
double ans = 1;
if (dfs(table, visited, query[i].first, query[i].second, ans))
res.push_back(ans);
else res.push_back(double(-1));
}
return res;
}
bool dfs(unordered_map<string, vector<pair<string, double>>>& table, unordered_set<string>& visited, string& s, string& e, double& ans) {
if (table.count(s) == 0) return false;
if (s == e) return true;
for (int i = 0; i < table[s].size(); i++) {
if (visited.count(table[s][i].first) == 0) {
visited.insert(table[s][i].first);
double old = ans;
ans *= table[s][i].second;
if (dfs(table, visited, table[s][i].first, e, ans))
return true;
ans = old; //当发现i节点走不通的时候,记得恢复ans并且擦去visited存的值
visited.erase(table[s][i].first);
}
}
return false;
}