这道题我觉得还是有一定难度的,特别是写DFS时候调试了很久才最终解决问题(不过也有可能是我对DFS理解不深的缘故)。难点在于作出了图之后,找寻某两个数之间的数量关系必须要遍历图上所有数相互间的数量关系,这个遍历过程耗费了不少时间。降低时间复杂度的方法目前还未想出,相当于是暴力求解了。
简单说说思路:作图时我是用map<string, vector<pair<string, double>>>来记录的,键是某个元素,值是这个数所对应的跟另外的数的数量关系的vector表。之后进行DFS时要对当前数用for循环遍历跟此数有数量关系的其他数(通过图寻找),但是每一个数又各自需要进行DFS,不好直接返回值,于是我就直接放了个引用值做参数来记录最终的结果。为了避免重复遍历,需要map来记录已经完成遍历的数的状态(未遍历为false,已遍历为true)。
void DFS(map<string, vector<pair<string, double>>> mp, map<string, bool>& visit, string target, string source, double num, double& res) {
vector<pair<string, double>> vec = mp[source];//找出跟当前数(source)有数量关系的其他数(通过图)
visit[source] = true;//已被遍历
int l = vec.size();
for (int i = 0; i < l; i++) {
if (vec[i].first == target) {
res = num * vec[i].second;//找到目标数,res记录结果(因为时引用值,结果会保存)
}
else {
if (!visit[vec[i].first]) {//找不到目标数,进行下一个DFS遍历
DFS(mp, visit, target, vec[i].first, num * vec[i].second, res);//修改当前数(source)与当前值(num)
}
}
}
visit[source] = false;//完成遍历恢复原来状态
}
class Solution {
public:
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
vector<double> res;
map<string, bool> visit;
map<string, vector<pair<string, double>>> mp;
for (int i = 0; i < values.size(); i++) {
visit[equations[i].first] = false;
visit[equations[i].second] = false;
pair<string, double> tmp;
tmp = { equations[i].second, values[i] };
mp[equations[i].first].push_back(tmp);
tmp = { equations[i].first, 1 / values[i] };
mp[equations[i].second].push_back(tmp);
}
map<string, vector<pair<string, double>>>::iterator it1, it2;
for (int i = 0; i < queries.size(); i++) {
map<string, bool>::iterator it;
for (it = visit.begin(); it != visit.end(); it++) {
(*it).second = false;//设置每个数的初始状态为false,即未被遍历
}
it1 = mp.find(queries[i].first);
it2 = mp.find(queries[i].second);
if (it1 == mp.end() || it2 == mp.end()) {//找不到被除数或除数,结果为-1.0
res.push_back(-1.0);
}
else {
if (queries[i].first == queries[i].second) {//被除数==除数,结果为1.0
res.push_back(1.0);
}
else {
double d = -1.0;
DFS(mp, visit, queries[i].second, queries[i].first, 1.0, d);
res.push_back(d);
}
}
}
return res;
}
};