-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path399.cpp
More file actions
72 lines (63 loc) · 2.24 KB
/
399.cpp
File metadata and controls
72 lines (63 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Author: btjanaka (Bryon Tjanaka)
// Problem: (LeetCode) 399
// Title: Evaluate Division
// Link: https://leetcode.com/problems/evaluate-division/
// Idea: Frame this as a graph problem where you can move around nodes and
// multiply the costs together. E.g. if you have a, b, and c, then moving from a
// to b is a/b, and b to c is b/c, so to get from a to c is a/b * b/c. Once we
// set up this graph, use a traversal algorithm to see if there is a path
// from c to d.
// Difficulty: Medium
// Tags: Graph, BFS, DFS
class Solution {
public:
vector<double> calcEquation(vector<vector<string>>& equations,
vector<double>& values,
vector<vector<string>>& queries) {
// Construct graph mapping from numerators to denominators.
unordered_map<string, vector<pair<string, double>>> g;
for (int i = 0; i < equations.size(); ++i) {
string &a = equations[i][0], b = equations[i][1];
double val = values[i];
if (g.find(a) == g.end()) g[a] = {};
if (g.find(b) == g.end()) g[b] = {};
// Add both a/b and b/a.
g[a].push_back({b, val});
g[b].push_back({a, 1.0 / val});
}
vector<double> res;
for (const auto& query : queries) {
const string &c = query[0], d = query[1];
// c or d not defined.
if (g.find(c) == g.end() || g.find(d) == g.end()) {
res.push_back(-1);
continue;
}
// Use BFS to see if we can find a path between the query's numerator and
// denominator.
unordered_set<string> visited;
queue<pair<string, double>>
q; // Stores node and the product along the path.
bool success = false;
q.push({c, 1.0}); // Start at c with product of 1.0.
while (!q.empty()) {
auto cur = q.front();
q.pop();
const string& node = cur.first;
double cost = cur.second;
if (node == d) {
res.push_back(cost);
success = true;
break;
}
if (visited.find(node) != visited.end()) continue;
visited.insert(node);
for (const auto& next : g[node]) {
q.push({next.first, next.second * cost});
}
}
if (!success) res.push_back(-1.0);
}
return res;
}
};