You are given an array of variable pairs equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string that represents a single variable.
You are also given some queries, where queries[j] = [Cj, Dj] represents the jth query where you must find the answer for Cj / Dj = ?
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.
💡 Note:Two separate components: {a,b} and {c,d}. No path between different components, so a/c and b/d are -1.0. Within components: b/a = 1/1.0 = 1.0, d/c = 1/1.0 = 1.0.
Constraints
1 ≤ equations.length ≤ 20
equations[i].length == 2
1 ≤ Ai.length, Bi.length ≤ 5
values.length == equations.length
0.0 < values[i] ≤ 20.0
1 ≤ queries.length ≤ 20
queries[i].length == 2
1 ≤ Cj.length, Dj.length ≤ 5
Ai, Bi, Cj, Dj consist of lowercase English letters and digits.
The key insight is to model division relationships as a weighted directed graph where each variable is a node and each equation creates bidirectional edges. Best approach uses DFS graph traversal to find paths between query variables, multiplying edge weights along the path. Time: O(Q × (V + E)), Space: O(V + E)
Common Approaches
✓
Optimized
⏱️ Time: N/A
Space: N/A
Brute Force Path Search
⏱️ Time: O(q × n!)
Space: O(n)
For every query, exhaustively search through all equations to find any sequence that connects the query variables. This involves checking all possible combinations and sequences of equations.
DFS Graph Traversal
⏱️ Time: O(E + Q × (V + E))
Space: O(V + E)
Model the division relationships as a weighted directed graph where each variable is a node and each equation creates bidirectional edges. Use DFS to traverse from source to target, multiplying weights along the path.
Algorithm Steps — Algorithm Steps
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct {
char* key;
double value;
} EdgeNode;
typedef struct {
char* key;
EdgeNode* edges;
int edgeCount;
int edgeCapacity;
} GraphNode;
typedef struct {
GraphNode* nodes;
int nodeCount;
int nodeCapacity;
} Graph;
typedef struct {
char** keys;
int count;
int capacity;
} VisitedSet;
Graph* createGraph() {
Graph* g = (Graph*)malloc(sizeof(Graph));
g->nodes = (GraphNode*)malloc(100 * sizeof(GraphNode));
g->nodeCount = 0;
g->nodeCapacity = 100;
return g;
}
int findNodeIndex(Graph* g, const char* key) {
for (int i = 0; i < g->nodeCount; i++) {
if (strcmp(g->nodes[i].key, key) == 0) {
return i;
}
}
return -1;
}
void addNode(Graph* g, const char* key) {
if (findNodeIndex(g, key) != -1) return;
if (g->nodeCount >= g->nodeCapacity) {
g->nodeCapacity *= 2;
g->nodes = (GraphNode*)realloc(g->nodes, g->nodeCapacity * sizeof(GraphNode));
}
g->nodes[g->nodeCount].key = (char*)malloc(strlen(key) + 1);
strcpy(g->nodes[g->nodeCount].key, key);
g->nodes[g->nodeCount].edges = (EdgeNode*)malloc(10 * sizeof(EdgeNode));
g->nodes[g->nodeCount].edgeCount = 0;
g->nodes[g->nodeCount].edgeCapacity = 10;
g->nodeCount++;
}
void addEdge(Graph* g, const char* from, const char* to, double value) {
int fromIdx = findNodeIndex(g, from);
if (fromIdx == -1) return;
GraphNode* node = &g->nodes[fromIdx];
if (node->edgeCount >= node->edgeCapacity) {
node->edgeCapacity *= 2;
node->edges = (EdgeNode*)realloc(node->edges, node->edgeCapacity * sizeof(EdgeNode));
}
node->edges[node->edgeCount].key = (char*)malloc(strlen(to) + 1);
strcpy(node->edges[node->edgeCount].key, to);
node->edges[node->edgeCount].value = value;
node->edgeCount++;
}
VisitedSet* createVisitedSet() {
VisitedSet* v = (VisitedSet*)malloc(sizeof(VisitedSet));
v->keys = (char**)malloc(100 * sizeof(char*));
v->count = 0;
v->capacity = 100;
return v;
}
int isVisited(VisitedSet* v, const char* key) {
for (int i = 0; i < v->count; i++) {
if (strcmp(v->keys[i], key) == 0) {
return 1;
}
}
return 0;
}
void addVisited(VisitedSet* v, const char* key) {
if (v->count >= v->capacity) {
v->capacity *= 2;
v->keys = (char**)realloc(v->keys, v->capacity * sizeof(char*));
}
v->keys[v->count] = (char*)malloc(strlen(key) + 1);
strcpy(v->keys[v->count], key);
v->count++;
}
void removeVisited(VisitedSet* v, const char* key) {
for (int i = 0; i < v->count; i++) {
if (strcmp(v->keys[i], key) == 0) {
free(v->keys[i]);
for (int j = i; j < v->count - 1; j++) {
v->keys[j] = v->keys[j + 1];
}
v->count--;
break;
}
}
}
double dfs(Graph* g, const char* start, const char* end, VisitedSet* visited) {
int startIdx = findNodeIndex(g, start);
if (startIdx == -1) {
return -1.0;
}
GraphNode* startNode = &g->nodes[startIdx];
// Check direct connection
for (int i = 0; i < startNode->edgeCount; i++) {
if (strcmp(startNode->edges[i].key, end) == 0) {
return startNode->edges[i].value;
}
}
addVisited(visited, start);
for (int i = 0; i < startNode->edgeCount; i++) {
const char* neighbor = startNode->edges[i].key;
if (!isVisited(visited, neighbor)) {
double result = dfs(g, neighbor, end, visited);
if (result != -1.0) {
removeVisited(visited, start);
return startNode->edges[i].value * result;
}
}
}
removeVisited(visited, start);
return -1.0;
}
double* calcEquation(char*** equations, int equationsSize, double* values, char*** queries, int queriesSize, int* returnSize) {
Graph* graph = createGraph();
// Build graph
for (int i = 0; i < equationsSize; i++) {
char* a = equations[i][0];
char* b = equations[i][1];
double val = values[i];
addNode(graph, a);
addNode(graph, b);
addEdge(graph, a, b, val);
addEdge(graph, b, a, 1.0 / val);
}
double* result = (double*)malloc(queriesSize * sizeof(double));
for (int i = 0; i < queriesSize; i++) {
char* start = queries[i][0];
char* end = queries[i][1];
if (strcmp(start, end) == 0) {
if (findNodeIndex(graph, start) != -1) {
result[i] = 1.0;
} else {
result[i] = -1.0;
}
continue;
}
VisitedSet* visited = createVisitedSet();
result[i] = dfs(graph, start, end, visited);
// Free visited set
for (int j = 0; j < visited->count; j++) {
free(visited->keys[j]);
}
free(visited->keys);
free(visited);
}
*returnSize = queriesSize;
return result;
}
int main() {
char line[50000];
// Parse equations
fgets(line, sizeof(line), stdin);
char*** equations = (char***)malloc(1000 * sizeof(char**));
int equationsSize = 0;
char* ptr = line;
while (*ptr && *ptr != '[') ptr++;
if (*ptr) ptr++;
while (*ptr && equationsSize < 1000) {
while (*ptr && (*ptr == ' ' || *ptr == ',' || *ptr == '\n')) ptr++;
if (*ptr == ']') break;
if (*ptr != '[') break;
ptr++;
equations[equationsSize] = (char**)malloc(2 * sizeof(char*));
// Parse first string
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
ptr++;
char* start = ptr;
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
int len = ptr - start;
equations[equationsSize][0] = (char*)malloc(len + 1);
strncpy(equations[equationsSize][0], start, len);
equations[equationsSize][0][len] = '\0';
ptr++;
}
}
// Parse second string
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
ptr++;
char* start = ptr;
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
int len = ptr - start;
equations[equationsSize][1] = (char*)malloc(len + 1);
strncpy(equations[equationsSize][1], start, len);
equations[equationsSize][1][len] = '\0';
ptr++;
}
}
while (*ptr && *ptr != ']') ptr++;
if (*ptr) ptr++;
equationsSize++;
}
// Parse values
fgets(line, sizeof(line), stdin);
double* values = (double*)malloc(1000 * sizeof(double));
int valuesSize = 0;
ptr = line;
while (*ptr && *ptr != '[') ptr++;
if (*ptr) ptr++;
while (*ptr && valuesSize < 1000) {
while (*ptr && (*ptr == ' ' || *ptr == ',' || *ptr == '\n')) ptr++;
if (*ptr == ']') break;
if (!isdigit(*ptr) && *ptr != '.') break;
values[valuesSize] = strtod(ptr, &ptr);
valuesSize++;
}
// Parse queries
fgets(line, sizeof(line), stdin);
char*** queries = (char***)malloc(1000 * sizeof(char**));
int queriesSize = 0;
ptr = line;
while (*ptr && *ptr != '[') ptr++;
if (*ptr) ptr++;
while (*ptr && queriesSize < 1000) {
while (*ptr && (*ptr == ' ' || *ptr == ',' || *ptr == '\n')) ptr++;
if (*ptr == ']') break;
if (*ptr != '[') break;
ptr++;
queries[queriesSize] = (char**)malloc(2 * sizeof(char*));
// Parse first string
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
ptr++;
char* start = ptr;
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
int len = ptr - start;
queries[queriesSize][0] = (char*)malloc(len + 1);
strncpy(queries[queriesSize][0], start, len);
queries[queriesSize][0][len] = '\0';
ptr++;
}
}
// Parse second string
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
ptr++;
char* start = ptr;
while (*ptr && *ptr != '"') ptr++;
if (*ptr) {
int len = ptr - start;
queries[queriesSize][1] = (char*)malloc(len + 1);
strncpy(queries[queriesSize][1], start, len);
queries[queriesSize][1][len] = '\0';
ptr++;
}
}
while (*ptr && *ptr != ']') ptr++;
if (*ptr) ptr++;
queriesSize++;
}
int returnSize;
double* result = calcEquation(equations, equationsSize, values, queries, queriesSize, &returnSize);
printf("[");
for (int i = 0; i < returnSize; i++) {
if (i > 0) printf(",");
// Format to match Go JSON output exactly
if (result[i] == -1.0) {
printf("-1");
} else if (result[i] == (int)result[i]) {
// Integer values
printf("%.0f", result[i]);
} else {
// Use %.17g for maximum precision to match Go's JSON output
printf("%.17g", result[i]);
}
}
printf("]\n");
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
n
2n
✓ Linear Growth
Space Complexity
n
2n
✓ Linear Space
185.0K Views
MediumFrequency
~25 minAvg. Time
4.5K Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.