题目
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. Returnvector<double>
.
题目分析
一开始,看到这道题的时候,想过用并查集的方法来确定是否可解,后来发现并查集行不通,通过dfs来看能否寻找到路径更合适。
并查集举例:
["a", "e"]["b", "e"]
这里建立并查集后,因为e的上源是a和b,所以没法通过寻找parent来确定是否有解。
解题步骤:
1. 首先,该题目的输入是string,和平时acm中简便的int不同,因此需要将string映射到int。这里建立了一个map<string, int> idx
。但其实通过建立一个map包含map也可以直接处理,但可能不够熟练,所以就还是用一个映射来解决这个string的问题
2. 建立一个graph,我把这个division的两个参数看作结点,求出来的value作为边的权值,建立图。
3. 通过dfs搜索,看是否有路径,如果没有路径则返回0(因为输入都是正整数,不可能出现0),且继续搜索,若有路径则直接返回,因为计算出的数值具有唯一性。
源代码
class Solution {
public:
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
//若可以计算,则通过DFS找到路径
unordered_map<string, int> idx;
int cnt = 0;
//对应编号
for (int i = 0; i < equations.size(); i++) {
if (idx.count(equations[i].first) == 0) {
idx[equations[i].first] = cnt++;
}
if (idx.count(equations[i].second) == 0)
idx[equations[i].second] = cnt++;
}
vector<int> parent(cnt, 0);
vector<vector<double> > graph(cnt, vector<double>(cnt, -1));
//make graph
//make graph
for (int i = 0; i < equations.size(); i++) {
int a = idx[equations[i].first];
int b = idx[equations[i].second];
graph[a][b] = values[i];
graph[b][a] = 1.0 / values[i];
//cout << graph[b][a];
//parent[b] = find(a, parent);
}
vector<double> ans(queries.size(), 0);
// find answer
for (int i = 0; i < queries.size(); i++) {
if (idx.count(queries[i].first) == 0
|| idx.count(queries[i].second) == 0)
ans[i] = -1;
else if (graph[idx[queries[i].first]][idx[queries[i].second]] != -1)
ans[i] = graph[idx[queries[i].first]][idx[queries[i].second]];
else {
ans[i] = dfs(graph, idx[queries[i].first], idx[queries[i].first], idx[queries[i].second], parent);
if (ans[i] == 0)
ans[i] = -1;
}
}
return ans;
}
double dfs(vector<vector<double> >& graph,int src, int a, int b, vector<int>& parent) {
// cout << graph[a][b] << endl;
if (a == b)
return 1;
for (int i = 0; i < graph[a].size(); i++) {
if (graph[a][i] != -1 && src != i) {
double ans = dfs(graph, a, i, b, parent);
if (ans != 0)
return graph[a][i] * ans;
}
}
return 0;
}
};