Evaluate Division - BFS
You are given an array of variable pairs equations
and an array of real numbers values
, where equations[i] = [A<sub>i</sub>, B<sub>i</sub>]
and values[i]
represent the equation A<sub>i</sub> / B<sub>i</sub> = values[i]
. Each A<sub>i</sub>
or B<sub>i</sub>
is a string that represents a single variable.
You are also given some queries
, where queries[j] = [C<sub>j</sub>, D<sub>j</sub>]
represents the j<sup>th</sup>
query where you must find the answer for C<sub>j</sub> / D<sub>j</sub> = ?
.
Return the answers to all queries. If a single answer cannot be determined, return -1.0
.
Note: The input is always valid. You may assume that evaluating the queries will not result in division by zero and that there is no contradiction.
Note: The variables that do not occur in the list of equations are undefined, so the answer cannot be determined for them.
Example 1:
Input: equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
Output: [6.00000,0.50000,-1.00000,1.00000,-1.00000]
Explanation:
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 ]
note: x is undefined => -1.0
Example 2:
Input: equations = [["a","b"],["b","c"],["bc","cd"]], values = [1.5,2.5,5.0], queries = [["a","c"],["c","b"],["bc","cd"],["cd","bc"]]
Output: [3.75000,0.40000,5.00000,0.20000]
Example 3:
Input: equations = [["a","b"]], values = [0.5], queries = [["a","b"],["b","a"],["a","c"],["x","y"]]
Output: [0.50000,2.00000,-1.00000,-1.00000]
1) Explain the problem
The problem is to evaluate division queries based on given equations and values. Each equation represents a relationship between two variables, and we need to compute the result of the division for a set of queries. If a result cannot be determined, return -1.0.
2) Short easy to remember solution/approach
Use a graph to represent the relationships between variables.
Use Breadth-First Search (BFS) to evaluate the division queries by traversing the graph.
3) Solution in JavaScript with code commenting
function calcEquation(equations, values, queries) {
const graph = {};
// Build the graph
equations.forEach(([A, B], index) => {
if (!graph[A]) graph[A] = {};
if (!graph[B]) graph[B] = {};
graph[A][B] = values[index];
graph[B][A] = 1 / values[index];
});
// BFS function to find the value of division
const bfs = (start, end) => {
if (!(start in graph) || !(end in graph)) return -1.0;
if (start === end) return 1.0;
const queue = [[start, 1.0]];
const visited = new Set();
while (queue.length > 0) {
const [current, product] = queue.shift();
if (current === end) return product;
visited.add(current);
for (const neighbor in graph[current]) {
if (!visited.has(neighbor)) {
queue.push([neighbor, product * graph[current][neighbor]]);
}
}
}
return -1.0;
};
// Evaluate each query
return queries.map(([C, D]) => bfs(C, D));
}
4) Explanation of the solution in an easy-to-understand way with a real-life example
Imagine you have a network of currency exchange rates. For example, if 1 USD is equal to 0.85 EUR and 1 EUR is equal to 0.75 GBP, and you want to find out how many GBP you can get for 1 USD, you multiply the exchange rates. This is similar to our problem, where we use a graph to represent the relationships and BFS to find the shortest path between the currencies.
5) Code explanation in pointers
Graph Initialization: Build a graph where each node represents a variable, and each edge represents the division value between variables.
BFS Function:
Base Case: If either the start or end variable is not in the graph, return -1.0.
Self-Division Case: If the start and end variables are the same, return 1.0.
Queue Initialization: Use a queue to manage the BFS traversal, starting with the start variable and an initial product of 1.0.
Visited Set: Keep track of visited nodes to avoid cycles.
Graph Traversal: While the queue is not empty, dequeue the front element and check if it matches the end variable. If it does, return the product. Otherwise, enqueue all unvisited neighbors with the updated product.
Query Evaluation: For each query, use BFS to find the result.
6) Complexities
Time Complexity: O(Q * (V + E)) where Q is the number of queries, V is the number of variables, and E is the number of edges. Each BFS traversal explores the graph.
Space Complexity: O(V + E) for storing the graph and visited set.
Using BFS, we ensure a level-by-level traversal to find the shortest path in terms of the number of edges, which helps in efficiently computing the division results.
Subscribe to my newsletter
Read articles from Abhi directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by