- Interview Questions
- /
- Problems
- /
- Maximize Amount After Two Days of Conversions
Maximize Amount After Two Days of Conversions
Start with one unit of a currency, trade through day 1 rates and then day 2 rates, and end holding the starting currency with as much as possible. A graph traversal problem about combining two best-rate tables. Solve it below in Python or JavaScript, then read the walkthrough.
Problem
You start with exactly 1.0 unit of the currency initialCurrency.
On day 1 you may make any number of conversions (including none) using the pairs pairs1 and rates rates1. The entry pairs1[i] = [from, to] means one unit of from buys rates1[i] units of to. You may also convert the other way: one unit of to buys 1 / rates1[i] units of from.
On day 2 you may again make any number of conversions using pairs2 and rates2, with the same rules. Day 1 rates cannot be used on day 2.
At the end of day 2 you must hold initialCurrency again. Return the largest amount of it you can end with.
The rates on each day are consistent: there are no contradictions and no cycles, so on a given day there is at most one way to get from one currency to another. Answers within 10⁻⁵ of the expected value are accepted.
Example 1
- Input
- initialCurrency = "USD", pairs1 = [["USD","EUR"],["EUR","JPY"]], rates1 = [2.0, 4.0], pairs2 = [["JPY","GBP"],["GBP","USD"]], rates2 = [0.5, 0.5]
- Output
- 2.0
On day 1, USD → EUR → JPY turns 1 USD into 8 JPY. On day 2, JPY → GBP → USD turns 8 JPY into 8 × 0.5 × 0.5 = 2 USD. Stopping at EUR would not help, because EUR has no day 2 rate.
Example 2
- Input
- initialCurrency = "NGN", pairs1 = [["NGN","EUR"]], rates1 = [9.0], pairs2 = [["NGN","EUR"]], rates2 = [6.0]
- Output
- 1.5
Buy 9 EUR on day 1. On day 2, each EUR converts back at 1/6, giving 9 / 6 = 1.5 NGN.
Example 3
- Input
- initialCurrency = "AAA", pairs1 = [["BBB","CCC"]], rates1 = [2.0], pairs2 = [["CCC","DDD"]], rates2 = [3.0]
- Output
- 1.0
Neither day mentions AAA, so no trade is possible. Doing nothing keeps 1.0.
Constraints
- 1 ≤ pairs1.length, pairs2.length ≤ 10, with rates1 and rates2 the same lengths
- Currency names are 1 to 3 uppercase letters.
- 0.1 ≤ rates1[i], rates2[i] ≤ 10.0
- Neither day's conversion graph has contradictions or cycles.
- The answer is at most 5 × 10¹⁰.
Practice
Runs 12 tests in your browser. Python loads on the first run (about 6 MB, then cached). Press ⌘/Ctrl + Enter to run.
Get asked Maximize Amount After Two Days of Conversions in a real interview?
Interview Solver gives you a working solution live, during your actual coding interview. Invisible to screensharing.
How to solve Maximize Amount After Two Days of Conversions
Pattern: Graph traversal with multiplied edge weights
Treat each day as a graph: currencies are nodes, and each pair is an edge with weight rate one way and 1 / rate the other. Following a path multiplies the weights.
The two days only meet at one moment: the currency you hold at the end of day 1. Call it c. The best plan through c is "get as much c as possible on day 1" times "convert c back to the start currency on day 2". So you need two tables:
day1[c]: how muchcone unit of the start currency buys on day 1.day2[c]: how muchcone unit of the start currency buys on day 2. Convertingcback gives1 / day2[c]per unit.
The answer is the largest day1[c] / day2[c] over every currency reachable on both days. The start currency itself is always in both tables with value 1, which covers doing nothing. Because neither graph has cycles, each table is a single DFS or BFS from the start currency.
Approach 1: Enumerate every pair of paths
Search every simple path on day 1 from the start, and for each ending currency search every simple path on day 2 back to the start. Correct, but it redoes the day 2 search for every day 1 endpoint and does not use the fact that each day has at most one path between two currencies.
Time O(n · m) · Space O(n + m)
Approach 2: Bellman-Ford style relaxation
Keep a best-amount table for day 1, initialized to 1 for the start currency, and relax every edge in both directions until nothing improves. Seed the day 2 table with the day 1 amounts and relax again; read off the start currency. This is the general method that also handles graphs with several paths, at the cost of repeated passes.
Time O(V · E) · Space O(V)
Approach 3: One traversal per day, then combine
- Build an undirected adjacency list for each day with weights
rateand1 / rate. - DFS from the start currency on day 1, setting
day1[next] = day1[cur] * weightthe first time each currency is reached. Do the same for day 2. - Return the maximum of
day1[c] / day2[c]over currencies in both tables.
Each traversal visits every reachable edge once.
Time O(n + m) · Space O(n + m)
| Approach | Time | Space |
|---|---|---|
| Enumerate every pair of paths | O(n · m) | O(n + m) |
| Bellman-Ford style relaxation | O(V · E) | O(V) |
| One traversal per day, then combine | O(n + m) | O(n + m) |
Solution code
Try the practice editor first. Both solutions pass every test above.
Maximize Amount After Two Days of Conversions solution in Python
from collections import defaultdict
def _rates_from(start: str, pairs: list[list[str]], rates: list[float]) -> dict[str, float]:
graph = defaultdict(list)
for (a, b), r in zip(pairs, rates):
graph[a].append((b, r))
graph[b].append((a, 1 / r))
amount = {start: 1.0}
stack = [start]
while stack:
cur = stack.pop()
for nxt, r in graph[cur]:
if nxt not in amount:
amount[nxt] = amount[cur] * r
stack.append(nxt)
return amount
def max_amount(
initial_currency: str,
pairs1: list[list[str]],
rates1: list[float],
pairs2: list[list[str]],
rates2: list[float],
) -> float:
day1 = _rates_from(initial_currency, pairs1, rates1)
day2 = _rates_from(initial_currency, pairs2, rates2)
# Hold c overnight: day1[c] units, each worth 1 / day2[c] at the end.
return max(day1[c] / day2[c] for c in day1 if c in day2)Maximize Amount After Two Days of Conversions solution in JavaScript
function ratesFrom(start, pairs, rates) {
const graph = new Map();
const add = (a, b, r) => {
if (!graph.has(a)) graph.set(a, []);
graph.get(a).push([b, r]);
};
pairs.forEach(([a, b], i) => {
add(a, b, rates[i]);
add(b, a, 1 / rates[i]);
});
const amount = new Map([[start, 1]]);
const stack = [start];
while (stack.length) {
const cur = stack.pop();
for (const [next, r] of graph.get(cur) ?? []) {
if (!amount.has(next)) {
amount.set(next, amount.get(cur) * r);
stack.push(next);
}
}
}
return amount;
}
function maxAmount(initialCurrency, pairs1, rates1, pairs2, rates2) {
const day1 = ratesFrom(initialCurrency, pairs1, rates1);
const day2 = ratesFrom(initialCurrency, pairs2, rates2);
let best = 0;
for (const [c, amt] of day1) {
// Hold c overnight: amt units, each worth 1 / day2[c] at the end.
if (day2.has(c)) best = Math.max(best, amt / day2.get(c));
}
return best;
}Common mistakes
- Forgetting the reverse edges. A pair [from, to] can be traded both ways, at rate and at 1 / rate.
- Only considering currencies reachable on day 1 and assuming they can always be converted back on day 2.
- Leaving out the option of not trading at all, which is what keeps the answer at least 1.0 when nothing helps.
- Running day 2 from each candidate currency separately instead of once from the start currency and inverting.
- Mixing up the direction of day 2: you need the rate from c back to the start, which is the reciprocal of the start-to-c rate.
What interviewers look for
Say the decomposition clearly: "the only thing that links the days is the currency I hold overnight, so I'll compute the best amount of every currency after day 1 and the best way back from every currency on day 2." That turns a confusing two-phase problem into two independent traversals.
Then point out the trick for day 2: instead of searching from every currency to the start, search once from the start and take reciprocals. Interviewers like hearing that you used the no-cycles guarantee to justify a single DFS, and that you would switch to Bellman-Ford if the graphs could have several paths.
Follow-up questions
What if the graphs could have cycles with consistent rates?
Consistency means every path between two currencies gives the same product, so the first time a DFS reaches a currency is already its best rate. The same algorithm works; the visited set just stops it from looping.
What if rates could be inconsistent, allowing arbitrage?
Take logarithms so multiplication becomes addition, and negate them so the best product becomes a shortest path. An arbitrage loop is then a negative cycle, which Bellman-Ford detects. If one is reachable, the amount is unbounded.
How would this extend to k days?
Keep a table of the best amount of every currency at the end of each day. Day i starts from the previous table and relaxes that day's edges, so it is a Bellman-Ford pass per day seeded with many sources. The answer is the start currency's entry after day k.
Companies that ask Maximize Amount After Two Days of Conversions
Maximize Amount After Two Days of Conversions is tagged by 92 companies in our interview dataset. The score shows how often it comes up at each company.
- Coforge100%
- Deezer95%
- Oscar Health92%
- Elastic91%
- Trend Micro83%
- Continental83%
- Wisetech Global82%
- Bae Systems81%
- Egen81%
- Guardant Health81%
- Workiva81%
- Highradius80%
- Unanet79%
- Lacework78%
- Tenstorrent75%
- Adevinta75%
- F5 Networks75%
- Peraton74%
- General Atomics72%
- Zimmer Biomet69%
- Mercedes Benz68%
- Quantcast68%
- Mixi67%
- Cerebras Systems66%
and 68 more.
Practice next
Get live help in the real interview
Working solutions in real time during your actual interview. Invisible to screensharing.
Start Free TrialNo credit card required