Unit Conversion I
MedPrompt
There are n types of units indexed from 0 to n - 1. You are given a 2D integer array conversions of length n - 1, where conversions[i] = [sourceUniti, targetUniti, conversionFactori]. This indicates that a single unit of type sourceUniti is equivalent to conversionFactori units of type targetUniti.
Return an array baseUnitConversion of length n, where baseUnitConversion[i] is the number of units of type i equivalent to a single unit of type 0. Since the answer may be large, return each baseUnitConversion[i] modulo 109 + 7.
Example 1:
Input: conversions = [[0,1,2],[1,2,3]]
Output: [1,2,6]
Explanation:
- Convert a single unit of type 0 into 2 units of type 1 using
conversions[0]. - Convert a single unit of type 0 into 6 units of type 2 using
conversions[0], thenconversions[1].

Example 2:
Input: conversions = [[0,1,2],[0,2,3],[1,3,4],[1,4,5],[2,5,2],[4,6,3],[5,7,4]]
Output: [1,2,3,8,10,6,30,24]
Explanation:
- Convert a single unit of type 0 into 2 units of type 1 using
conversions[0]. - Convert a single unit of type 0 into 3 units of type 2 using
conversions[1]. - Convert a single unit of type 0 into 8 units of type 3 using
conversions[0], thenconversions[2]. - Convert a single unit of type 0 into 10 units of type 4 using
conversions[0], thenconversions[3]. - Convert a single unit of type 0 into 6 units of type 5 using
conversions[1], thenconversions[4]. - Convert a single unit of type 0 into 30 units of type 6 using
conversions[0],conversions[3], thenconversions[5]. - Convert a single unit of type 0 into 24 units of type 7 using
conversions[1],conversions[4], thenconversions[6].
Constraints:
2 <= n <= 105conversions.length == n - 10 <= sourceUniti, targetUniti < n1 <= conversionFactori <= 109- It is guaranteed that unit 0 can be converted into any other unit through a unique combination of conversions without using any conversions in the opposite direction.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach tackles the problem by directly answering the question for each unit one by one. For every unit i (from 1 to n-1), we want to find the conversion factor from unit 0. We can achieve this by finding the path from unit 0 to unit i in the conversion graph and multiplying the factors along that path. A graph traversal algorithm like Breadth-First Search (BFS) or Depth-First Search (DFS) can be used to find this path. This entire process is repeated for all n-1 units, leading to a lot of repeated work.
Algorithm
- Build Graph: Represent the conversions as a directed graph. An adjacency list is a suitable data structure, where
adj[u]stores a list of pairs(v, factor), indicating that1 unit of u = factor units of v. - Initialize Result: Create an array
baseUnitConversionof sizen. SetbaseUnitConversion[0] = 1. - Iterate and Search: For each unit
ifrom 1 ton-1:- Perform a graph traversal (e.g., BFS) starting from unit 0 to find unit
i. - During the BFS, keep track of the cumulative conversion factor from the start node (0) to the current node.
- When a node
uwith cumulative factorF_uis processed, and it has a neighborvwith conversion factorw, the cumulative factor forvis(F_u * w) % MOD. - Once unit
iis found, its calculated cumulative factor is the answer. Store this inbaseUnitConversion[i].
- Perform a graph traversal (e.g., BFS) starting from unit 0 to find unit
- Return Result: Return the
baseUnitConversionarray.
Walkthrough
The algorithm proceeds as follows:
- First, we build a graph representation of the unit conversions. An adjacency list is a good choice, where for each conversion
[u, v, w], we add a directed edge fromutovwith weightw. - We initialize our result array,
baseUnitConversion, of sizen. We knowbaseUnitConversion[0]is 1. - Then, we loop through every other unit
ifrom 1 ton-1. - Inside the loop, for each
i, we start a fresh Breadth-First Search (BFS) from unit 0. The goal of this BFS is to find the path and the corresponding cumulative conversion factor to reachi. - The BFS queue will store pairs of
[node, cumulativeFactor]. We start by adding[0, 1]to the queue. - When we explore from a node
uwith factorF_uto its neighborvvia an edge with weightw, the new cumulative factor forvis(F_u * w) % MOD. - When our BFS reaches the target node
i, we record its computed cumulative factor inbaseUnitConversion[i]and can terminate that specific search. - After iterating through all
i, thebaseUnitConversionarray is complete and can be returned.
import java.util.*; class Solution { private static final int MOD = 1_000_000_007; public long[] unitConversion(int n, int[][] conversions) { List<List<int[]>> adj = new ArrayList<>(); for (int i = 0; i < n; i++) { adj.add(new ArrayList<>()); } for (int[] conv : conversions) { adj.get(conv[0]).add(new int[]{conv[1], conv[2]}); } long[] baseUnitConversion = new long[n]; baseUnitConversion[0] = 1; for (int i = 1; i < n; i++) { // For each target unit 'i', run a separate BFS from 0 Queue<long[]> bfsQueue = new LinkedList<>(); // {node, cumulativeFactor} bfsQueue.offer(new long[]{0, 1}); boolean[] visited = new boolean[n]; visited[0] = true; while(!bfsQueue.isEmpty()){ long[] current = bfsQueue.poll(); int u = (int)current[0]; long uFactor = current[1]; if(u == i){ baseUnitConversion[i] = uFactor; break; // Found the path to i, can stop this BFS } for(int[] edge : adj.get(u)){ int v = edge[0]; int factor = edge[1]; if(!visited[v]){ visited[v] = true; long vFactor = (uFactor * factor) % MOD; bfsQueue.offer(new long[]{v, vFactor}); } } } } return baseUnitConversion; }}Complexity
Time
O(n^2) - We iterate through `n-1` target units. For each unit, we perform a graph traversal (BFS/DFS) which takes O(V+E) = O(n) time in the worst case. This results in a total time complexity of O(n * n).
Space
O(n) - The adjacency list requires O(n) space. For each of the n-1 traversals, the queue and visited array also require O(n) space.
Trade-offs
Pros
Conceptually simple and directly follows the problem's request for each unit.
Easy to implement without needing deeper graph theory insights.
Cons
Highly inefficient due to redundant computations. The same subpaths (e.g., from unit 0 to some intermediate unit) are traversed multiple times across the different searches.
Will likely result in a 'Time Limit Exceeded' error for large inputs due to its quadratic time complexity.
Solutions
Solution
class Solution {private final int mod = (int)1 e9 + 7;private List<int[]>[] g;private int[] ans;private int n;public int[] baseUnitConversions(int[][] conversions) { n = conversions.length + 1; g = new List[n]; Arrays.setAll(g, k->new ArrayList<>()); ans = new int[n]; for (var e : conversions) { g[e[0]].add(new int[]{e[1], e[2]}); } dfs(0, 1); return ans; }private void dfs(int s, long mul) { ans[s] = (int)mul; for (var e : g[s]) { dfs(e[0], mul * e[1] % mod); } }}Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.