题意
给定一系列除法等式,比如a/b = 3, b/c = 2, 有一个query array,求诸如a/c 的答案
链接
https://leetcode.com/problems/evaluate-division/
思考
诸如a/b = 3, b / c = 2的等式实际上可以转化成图,a, b, c为顶点,a->b = 3, b -> c = 2, b -> a = 1/3, c->b = 1/2, 比如a/c其实就是在求a->c的权重是多少
题解
建立一个邻接矩阵,包含每个顶点到每个顶点的权重,用dfs搜索路径并把路径的权重相乘
解法
DFS
class Solution {
public:
unordered_map <string, vector<pair<string, double>>> g;
vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
vector<double> res;
for(int i = 0; i < equations.size(); i++) {
string a = equations[i][0];
string b = equations[i][1];
double val1 = values[i];
double val2 = 1/values[i];
g[a].push_back({b, val1});
g[b].push_back({a, val2});
}
for(auto& query: queries) {
string a = query[0];
string b = query[1];
if(!g.count(a) || !g.count(b)) {
res.push_back(-1.0);
continue;
}
//防止dfs遍历已经遍历过的节点,防止死循环
unordered_set<string> st;
res.push_back(dfs(a, b, st));
}
return res;
}
//a是起点,b是终点
double dfs(string& a, string& b , unordered_set<string>& st) {
if(a == b) return 1.0;
st.insert(a);
for(auto& [neigh, val]: g[a]) {
if(!st.count(neigh)) {
auto res = val * dfs(neigh, b, st);
//这里判断res而不是val,因为dfs如果没有搜索到一条路径,那么就会返回-1.0,负数的话就不管,搜索下一条可行的路径
if(res > 0) {
return res;
}
}
}
return -1.0;
}
};
BFS
class Solution {
public:
unordered_map<string, vector<pair<string, double>>> g;
vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
//construct a graph
vector<double> res;
for(int i = 0; i < equations.size(); i++) {
vector<string> v = equations[i];
double val1 = values[i];
double val2 = 1.0/values[i];
g[v[0]].push_back({v[1], val1});
g[v[1]].push_back({v[0], val2});
}
for(auto& query: queries) {
unordered_set<string> st;
res.push_back(cal(query, st));
}
return res;
}
double cal(vector<string>& query, unordered_set<string>& st) {
double res = -1;
queue<pair<string, double>> q;
if(!g.count(query[0])) {
return -1.0;
}
q.push({query[0], 1});
st.insert(query[0]);
while(q.size()) {
pair<string, double> node = q.front();
q.pop();
if(node.first == query[1]) {
return node.second;
}
for(auto& e: g[node.first]) {
if(!st.count(e.first)) {
st.insert(e.first);
q.push({e.first, e.second * node.second});
}
}
}
return -1.0;
}
};
时间复杂度:
O
(
V
+
E
)
O(V+E)
O(V+E) V是图的顶点数E是图的边数
空间复杂度:
O
(
图
+
E
)
O(图+E)
O(图+E)
对于这道题而言,bfs会相对比较慢,因为他要维护更多的状态(维护起点到某个点的权重)