Description
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
class Solution {
private:
vector<string> path; //保存dfs的路径,便于后面的计算
//re记录节点是否已被访问,refl是变量到数组下标的映射,l是邻接链表
void dfs(string & s, string & e, list<string> * l, map<string, int> & refl, map<string, int> & re) {
path.push_back(s);
int index = refl[s];
std::list<string>::iterator it;
re[s] = 0;
for (it = l[index].begin(); it != l[index].end(); it++) {
if (*it == e) { //找到除数,dfs终止
path.push_back(*it);
return;
}
if (re[*it]) {
dfs(*it, e, l, refl, re);
if (path[path.size() - 1] == e)
return;
path.pop_back();
}
}
}
public:
vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) {
int e_size = equations.size();
list<string> div[2 * e_size]; //邻接链表,每一个变量对应一个index
map<string, int> refl; //变量到index的映射
//构造邻接链表
for (int i = 0, index = 0; i < e_size; i++) {
pair<string, string> equ(equations[i].first, equations[i].second);
if (refl.count(equ.first) == 0) { //判断变量是否已经存在
refl.insert(pair<string, int>(equ.first, index));
index++;
}
if (refl.count(equ.second) == 0) {
refl.insert(pair<string, int>(equ.second, index));
index++;
}
div[refl[equ.first]].push_back(equ.second);
div[refl[equ.second]].push_back(equ.first);
}
vector<double> result;
int size = queries.size();
for (int i = 0; i < size; i++) {
pair<string, string> que(queries[i].first, queries[i].second);
if (refl.count(que.first) == 0 || refl.count(que.second) == 0) //变量没有在equations中出现的情况
result.push_back(-1.0);
else if (que.first == que.second) //除数等于被除数的情况
result.push_back(1.0);
else {
map<string, int> re = refl;
std::map<string, int>::iterator m_it; //用来记录dfs中未被访问的节点
for (m_it = re.begin(); m_it != re.end(); m_it++) {
m_it -> second = 1;
}
if (!path.empty()) {
path.clear();
}
dfs(que.first, que.second, div, refl, re);
if (path.size() >= 2){ //相除有结果
int p_size = path.size();
double mul = 1.0;
for (int j = 0; j < p_size - 1; j++) {
pair<string, string> temp1(path[j], path[j+1]); //构造算式
std::vector<pair<string, string>>:: iterator e_it;
e_it = find(equations.begin(), equations.end(), temp1);//找出算式的位置,方便取值
if (e_it != equations.end()) {
mul = mul * values[e_it - equations.begin()];
}
else { //除数和被除数颠倒的情况
pair<string, string> temp2(path[j + 1], path[j]);
e_it = find(equations.begin(), equations.end(), temp2);
mul = mul / values[e_it - equations.begin()];
}
}
result.push_back(mul);
}
else //相除无结果
result.push_back(-1.0);
}
}
return result;
}
};