399. Evaluate Division
DFS
see in DFS
class Solution {
class Data {
String node;
double value;
Data(String node, double value) {
this.node = node;
this.value = value;
}
}
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
Map<String, List<Data>> graph = buildGraph(equations, values);
double[] result = new double[queries.size()];
for (int i = 0 ; i < queries.size(); i++) {
List<String> querie = queries.get(i);
String start = querie.get(0);
String end = querie.get(1);
Set<String> visited = new HashSet<>();
visited.add(start);
result[i] = dfs(graph, start, end, visited);
}
return result;
}
private double dfs(Map<String, List<Data>> graph, String start, String end, Set<String> visited) {
if (graph.get(start) == null || graph.get(end) == null) { // terminal condition
return -1;
}
// terminal condition, at last to == end, so return 1, then bottom up to cal result 1*...value*value...
if (start.equals(end)) {
return 1;
}
for (Data child : graph.get(start)) {
String to = child.node;
double value = child.value;
if (visited.contains(to)) {
continue;
}
visited.add(to);
double temp = dfs(graph, to, end, visited);
visited.remove(to);
if (temp != -1) {
return temp*value;
}
}
return -1;
}
private Map<String, List<Data>> buildGraph(List<List<String>> equations, double[] values) {
Map<String, List<Data>> map = new HashMap<>();
for (int i = 0; i < equations.size(); i++) {
List<String> equation = equations.get(i);
String from = equation.get(0);
String to = equation.get(1);
map.putIfAbsent(from, new ArrayList<>());
map.get(from).add(new Data(to, values[i]));
map.putIfAbsent(to, new ArrayList<>());
map.get(to).add(new Data(from, 1.0/values[i]));
}
return map;
}
}
/*
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 ]
query c/d
a = 2b
b = 3c
2 3
a - b - c
a/c = 6
b/a = 1/2
a/e = -1 (can't find one of them in graph, return -1)
a/a = 1 (can find in graph)
x/x = -1 (can't find one of them in graph, return -1)
If a single answer cannot be determined, return -1.0.
ex: a/e
a/b = 1.5
b/c = 2.5 => b = 2.5c => bc = 2.5c/d = 5 => c/d = 2
bc/cd = 5
1.5 2.5 2
a - b - c - d
a/c = 1.5*2.5 =
c/b = 1/2.5
bc/cd = b/d = 5
cd/bc = d/b = 1/5
*/
BFS
T: O(q*n), q: queries times, n: graph nodes number
S: O(n)
class Solution {
class Data {
String node;
double value;
Data(String node, double value) {
this.node = node;
this.value = value;
}
}
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
Map<String, List<Data>> graph = buildGraph(equations, values);
double[] result = new double[queries.size()];
for (int i = 0 ; i < queries.size(); i++) {
List<String> querie = queries.get(i);
String start = querie.get(0);
String end = querie.get(1);
//System.out.println("query -> start:" + start + ",end:" + end);
result[i] = bfs(graph, start, end);
}
return result;
}
private double bfs(Map<String, List<Data>> graph, String start, String end) {
// eliminate duplicate
if (!graph.containsKey(start) || !graph.containsKey(end)) {
return -1.0;
}
if (start.equals(end)) {
return 1.0;
}
Queue<Data> queue = new LinkedList<>();
queue.offer(new Data(start, 1.0));
Set<String> visited = new HashSet<>();
visited.add(start);
while (!queue.isEmpty()) {
Data cur = queue.poll();
String from = cur.node;
double fromValue = cur.value;
for (Data child : graph.get(from)) {
String to = child.node;
double value = child.value;
if (visited.contains(to)) {
continue;
}
//System.out.println("cur:" + cur + ",to:" + to + ",value:" + value);
double result = fromValue*value;
queue.offer(new Data(to, result));
visited.add(to);
if (end.equals(to)) {
//System.out.println("cur:" + cur + ", to:" + to + ",end:" + end);
return result;
}
}
}
return -1.0;
}
private Map<String, List<Data>> buildGraph(List<List<String>> equations, double[] values) {
Map<String, List<Data>> map = new HashMap<>();
for (int i = 0; i < equations.size(); i++) {
List<String> equation = equations.get(i);
String from = equation.get(0);
String to = equation.get(1);
map.putIfAbsent(from, new ArrayList<>());
map.get(from).add(new Data(to, values[i]));
map.putIfAbsent(to, new ArrayList<>());
map.get(to).add(new Data(from, 1.0/values[i]));
}
return map;
}
}
/*
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 ]
query c/d
a = 2b
b = 3c
2 3
a - b - c
a/c = 6
b/a = 1/2
a/e = -1 (can't find one of them in graph, return -1)
a/a = 1 (can find in graph)
x/x = -1 (can't find one of them in graph, return -1)
If a single answer cannot be determined, return -1.0.
ex: a/e
a/b = 1.5
b/c = 2.5 => b = 2.5c => bc = 2.5c/d = 5 => c/d = 2
bc/cd = 5
1.5 2.5 2
a - b - c - d
a/c = 1.5*2.5 =
c/b = 1/2.5
bc/cd = b/d = 5
cd/bc = d/b = 1/5
*/
Last updated