Leetcode 399. Evaluate Division
You are given equations in the form of 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
.
The input is always valid. You may assume that evaluating the queries will result in no division by zero and there is no contradiction.
Example:
Input: equations = [ ["a", "b"], ["b", "c"] ],
values = [2.0, 3.0],
queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]
Output: [6.0, 0.5, -1.0, 1.0, -1.0]
To solve this problem, we will treat it as a graph traversal problem where variables are nodes and equations provide edges with weights:
A/B = k
, add edges A -> B with weight k
and B -> A with weight 1/k
.-1.0
.#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
unordered_map<string, unordered_map<string, double>> graph;
void addEdge(string from, string to, double value) {
graph[from][to] = value;
graph[to][from] = 1.0 / value;
}
bool dfs(const string &cur, const string &target, unordered_set<string> &visited, double &value) {
// If we have found the target
if (graph[cur].find(target) != graph[cur].end()) {
value *= graph[cur][target];
return true;
}
// Mark current node as visited
visited.insert(cur);
for (const auto &neighbor : graph[cur]) {
if (visited.find(neighbor.first) == visited.end()) {
double temp = value * neighbor.second;
if (dfs(neighbor.first, target, visited, temp)) {
// If target found during DFS, propagate the result upward
value = temp;
return true;
}
}
}
// Target was not reachable from this path
return false;
}
vector<double> calcEquation(vector<vector<string>>& equations, vector<double>& values, vector<vector<string>>& queries) {
// Build the graph
for (int i = 0; i < equations.size(); ++i) {
addEdge(equations[i][0], equations[i][1], values[i]);
}
vector<double> results;
// Process each query
for (const auto &query : queries) {
string from = query[0];
string to = query[1];
// If either node doesn’t exist in the graph
if (graph.find(from) == graph.end() || graph.find(to) == graph.end()) {
results.push_back(-1.0);
} else {
unordered_set<string> visited;
double value = 1.0;
results.push_back(dfs(from, to, visited, value) ? value : -1.0);
}
}
return results;
}
};
O(E)
, where E
is the number of equations.O(V)
per query. Hence, for Q
queries, it is O(Q * V)
.O(E + Q * V)
where E
is the number of edges (equations), Q
is the number of queries, and V
is the number of nodes (variables).Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?