Imagine you're building a universal unit converter for a scientific application! You have n different types of units (indexed from 0 to n-1), and you're given conversion relationships between them.
You receive a 2D array conversions where each element conversions[i] = [sourceUnit, targetUnit, conversionFactor] tells you that 1 unit of sourceUnit equals conversionFactor units of targetUnit.
Here's the challenge: Convert everything to a base unit system! You need to find how many units of each type are equivalent to 1 unit of type 0 (our base unit).
Since the conversion factors can get very large, return each result modulo 109 + 7.
Example: If 1 meter = 100 cm, and 1 cm = 10 mm, then 1 meter = 1000 mm. We want to express everything in terms of meters (unit 0).
Input & Output
example_1.py — Basic Unit Conversion
$Input:n = 3, conversions = [[0,1,10],[1,2,5]]
›Output:[1, 10, 50]
💡 Note:Unit 0 is base (factor 1). 1 unit of type 0 = 10 units of type 1, so factor for type 1 is 10. 1 unit of type 1 = 5 units of type 2, so 1 unit of type 0 = 10×5 = 50 units of type 2.
example_2.py — Disconnected Units
$Input:n = 4, conversions = [[0,1,2],[2,3,3]]
›Output:[1, 2, 0, 0]
💡 Note:Units 2 and 3 are not connected to unit 0, so their conversion factors are 0. Only units 0 and 1 are in the same connected component.
example_3.py — Large Factors
$Input:n = 2, conversions = [[0,1,1000000]]
›Output:[1, 1000000]
💡 Note:Direct conversion: 1 unit of type 0 equals 1,000,000 units of type 1. Since 1,000,000 < 10^9+7, no modulo needed.
Constraints
1 ≤ n ≤ 103
conversions.length == n - 1 or fewer (tree or forest structure)
The optimal solution models this as a weighted graph problem. Build an adjacency list from the conversions, then perform a single DFS/BFS traversal starting from unit 0. As we visit each unit, we multiply the current conversion factor by the edge weight to get the factor for the next unit. This gives us all conversion factors in O(n) time with just one graph traversal, much more efficient than running separate searches for each unit.
Common Approaches
✓
Brute Force (Multiple DFS)
⏱️ Time: O(n²)
Space: O(n)
For each unit, perform a separate graph traversal to find the conversion path back to unit 0. This approach rebuilds the graph exploration for every single unit, leading to redundant work.
Single DFS Traversal (Optimal)
⏱️ Time: O(n)
Space: O(n)
Model the problem as a weighted graph where each unit is a node and conversion factors are edge weights. Perform a single DFS or BFS starting from unit 0 to compute conversion factors to all reachable units in one traversal.
Brute Force (Multiple DFS) — Algorithm Steps
Build adjacency list from conversions array
For each unit i from 0 to n-1, run DFS to find path to unit 0
Track visited nodes and multiply conversion factors along the path
Store result for unit i in the answer array
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Build Graph
Create adjacency list with bidirectional edges
2
DFS for Unit 1
Run DFS from unit 0 to find path to unit 1
3
DFS for Unit 2
Run another DFS from unit 0 to find path to unit 2
4
Repeat
Continue for all remaining units - very inefficient!
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MOD 1000000007
#define MAX_N 1000
typedef struct Edge {
int neighbor;
int factor;
bool is_forward;
struct Edge* next;
} Edge;
static Edge* graph[MAX_N];
static bool visited[MAX_N];
static int result[MAX_N];
void parseArray(const char* str, int arr[][3], int* size) {
*size = 0;
const char* p = str;
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
while (*p == ' ' || *p == ',') p++;
if (*p == ']' || *p == '\0') break;
if (*p == '[') {
p++;
arr[*size][0] = (int)strtol(p, (char**)&p, 10);
while (*p == ' ' || *p == ',') p++;
arr[*size][1] = (int)strtol(p, (char**)&p, 10);
while (*p == ' ' || *p == ',') p++;
arr[*size][2] = (int)strtol(p, (char**)&p, 10);
while (*p && *p != ']') p++;
if (*p == ']') p++;
(*size)++;
} else {
p++;
}
}
}
long long modPow(long long base, long long exp, long long mod) {
long long result = 1;
while (exp > 0) {
if (exp % 2 == 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp /= 2;
}
return result;
}
void addEdge(int from, int to, int factor, bool is_forward) {
Edge* edge = (Edge*)malloc(sizeof(Edge));
edge->neighbor = to;
edge->factor = factor;
edge->is_forward = is_forward;
edge->next = graph[from];
graph[from] = edge;
}
void dfs(int node, long long factor) {
visited[node] = true;
result[node] = factor % MOD;
Edge* edge = graph[node];
while (edge) {
if (!visited[edge->neighbor]) {
long long new_factor;
if (edge->is_forward) {
new_factor = (factor * edge->factor) % MOD;
} else {
if (edge->factor % MOD == 0) {
new_factor = 0;
} else {
long long inv_factor = modPow(edge->factor, MOD-2, MOD);
new_factor = (factor * inv_factor) % MOD;
}
}
dfs(edge->neighbor, new_factor);
}
edge = edge->next;
}
}
int main() {
int n;
scanf("%d", &n);
char conversions_str[10000];
scanf(" %[^\n]", conversions_str);
// Initialize
memset(graph, 0, sizeof(graph));
memset(visited, false, sizeof(visited));
memset(result, 0, sizeof(result));
int conversions[1000][3];
int conversionsSize;
parseArray(conversions_str, conversions, &conversionsSize);
// Build graph
for (int i = 0; i < conversionsSize; i++) {
int source = conversions[i][0];
int target = conversions[i][1];
int factor = conversions[i][2];
addEdge(source, target, factor, true);
addEdge(target, source, factor, false);
}
dfs(0, 1);
for (int i = 0; i < n; i++) {
if (i > 0) printf(",");
printf("%d", result[i]);
}
printf("\n");
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n²)
We perform DFS for each of n units, and each DFS can visit up to n nodes
n
2n
⚠ Quadratic Growth
Space Complexity
O(n)
Space for adjacency list, recursion stack, and visited array
n
2n
⚡ Linearithmic Space
28.5K Views
MediumFrequency
~18 minAvg. Time
892 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.