Welcome to Subscribe On Youtube
3387. Maximize Amount After Two Days of Conversions
Description
You are given a string initialCurrency
, and you start with 1.0
of initialCurrency
.
You are also given four arrays with currency pairs (strings) and rates (real numbers):
pairs1[i] = [startCurrencyi, targetCurrencyi]
denotes that you can convert fromstartCurrencyi
totargetCurrencyi
at a rate ofrates1[i]
on day 1.pairs2[i] = [startCurrencyi, targetCurrencyi]
denotes that you can convert fromstartCurrencyi
totargetCurrencyi
at a rate ofrates2[i]
on day 2.- Also, each
targetCurrency
can be converted back to its correspondingstartCurrency
at a rate of1 / rate
.
You can perform any number of conversions, including zero, using rates1
on day 1, followed by any number of additional conversions, including zero, using rates2
on day 2.
Return the maximum amount of initialCurrency
you can have after performing any number of conversions on both days in order.
Note: Conversion rates are valid, and there will be no contradictions in the rates for either day. The rates for the days are independent of each other.
Example 1:
Input: initialCurrency = "EUR", pairs1 = [["EUR","USD"],["USD","JPY"]], rates1 = [2.0,3.0], pairs2 = [["JPY","USD"],["USD","CHF"],["CHF","EUR"]], rates2 = [4.0,5.0,6.0]
Output: 720.00000
Explanation:
To get the maximum amount of EUR, starting with 1.0 EUR:
- On Day 1:
- Convert EUR to USD to get 2.0 USD.
- Convert USD to JPY to get 6.0 JPY.
- On Day 2:
- Convert JPY to USD to get 24.0 USD.
- Convert USD to CHF to get 120.0 CHF.
- Finally, convert CHF to EUR to get 720.0 EUR.
Example 2:
Input: initialCurrency = "NGN", pairs1 = [["NGN","EUR"]], rates1 = [9.0], pairs2 = [["NGN","EUR"]], rates2 = [6.0]
Output: 1.50000
Explanation:
Converting NGN to EUR on day 1 and EUR to NGN using the inverse rate on day 2 gives the maximum amount.
Example 3:
Input: initialCurrency = "USD", pairs1 = [["USD","EUR"]], rates1 = [1.0], pairs2 = [["EUR","JPY"]], rates2 = [10.0]
Output: 1.00000
Explanation:
In this example, there is no need to make any conversions on either day.
Constraints:
1 <= initialCurrency.length <= 3
initialCurrency
consists only of uppercase English letters.1 <= n == pairs1.length <= 10
1 <= m == pairs2.length <= 10
pairs1[i] == [startCurrencyi, targetCurrencyi]
pairs2[i] == [startCurrencyi, targetCurrencyi]
1 <= startCurrencyi.length, targetCurrencyi.length <= 3
startCurrencyi
andtargetCurrencyi
consist only of uppercase English letters.rates1.length == n
rates2.length == m
1.0 <= rates1[i], rates2[i] <= 10.0
- The input is generated such that there are no contradictions or cycles in the conversion graphs for either day.
- The input is generated such that the output is at most
5 * 1010
.
Solutions
Solution 1
-
class Solution { public double maxAmount(String initialCurrency, List<List<String>> pairs1, double[] rates1, List<List<String>> pairs2, double[] rates2) { Map<String, Double> d1 = build(pairs1, rates1, initialCurrency); Map<String, Double> d2 = build(pairs2, rates2, initialCurrency); double ans = 0; for (Map.Entry<String, Double> entry : d2.entrySet()) { String currency = entry.getKey(); double rate = entry.getValue(); if (d1.containsKey(currency)) { ans = Math.max(ans, d1.get(currency) / rate); } } return ans; } private Map<String, Double> build(List<List<String>> pairs, double[] rates, String init) { Map<String, List<Pair<String, Double>>> g = new HashMap<>(); Map<String, Double> d = new HashMap<>(); for (int i = 0; i < pairs.size(); ++i) { String a = pairs.get(i).get(0); String b = pairs.get(i).get(1); double r = rates[i]; g.computeIfAbsent(a, k -> new ArrayList<>()).add(new Pair<>(b, r)); g.computeIfAbsent(b, k -> new ArrayList<>()).add(new Pair<>(a, 1 / r)); } dfs(g, d, init, 1.0); return d; } private void dfs( Map<String, List<Pair<String, Double>>> g, Map<String, Double> d, String a, double v) { if (d.containsKey(a)) { return; } d.put(a, v); for (Pair<String, Double> pair : g.getOrDefault(a, List.of())) { String b = pair.getKey(); double r = pair.getValue(); if (!d.containsKey(b)) { dfs(g, d, b, v * r); } } } }
-
class Solution { public: double maxAmount(string initialCurrency, vector<vector<string>>& pairs1, vector<double>& rates1, vector<vector<string>>& pairs2, vector<double>& rates2) { unordered_map<string, double> d1 = build(pairs1, rates1, initialCurrency); unordered_map<string, double> d2 = build(pairs2, rates2, initialCurrency); double ans = 0; for (const auto& [currency, rate] : d2) { if (d1.find(currency) != d1.end()) { ans = max(ans, d1[currency] / rate); } } return ans; } private: unordered_map<string, double> build(vector<vector<string>>& pairs, vector<double>& rates, const string& init) { unordered_map<string, vector<pair<string, double>>> g; unordered_map<string, double> d; for (int i = 0; i < pairs.size(); ++i) { const string& a = pairs[i][0]; const string& b = pairs[i][1]; double r = rates[i]; g[a].push_back({b, r}); g[b].push_back({a, 1 / r}); } auto dfs = [&](this auto&& dfs, const string& a, double v) -> void { if (d.find(a) != d.end()) { return; } d[a] = v; for (const auto& [b, r] : g[a]) { if (d.find(b) == d.end()) { dfs(b, v * r); } } }; dfs(init, 1.0); return d; } };
-
class Solution: def maxAmount( self, initialCurrency: str, pairs1: List[List[str]], rates1: List[float], pairs2: List[List[str]], rates2: List[float], ) -> float: d1 = self.build(pairs1, rates1, initialCurrency) d2 = self.build(pairs2, rates2, initialCurrency) return max(d1.get(a, 0) / r2 for a, r2 in d2.items()) def build( self, pairs: List[List[str]], rates: List[float], init: str ) -> Dict[str, float]: def dfs(a: str, v: float): d[a] = v for b, r in g[a]: if b not in d: dfs(b, v * r) g = defaultdict(list) for (a, b), r in zip(pairs, rates): g[a].append((b, r)) g[b].append((a, 1 / r)) d = {} dfs(init, 1) return d
-
type Pair struct { Key string Value float64 } func maxAmount(initialCurrency string, pairs1 [][]string, rates1 []float64, pairs2 [][]string, rates2 []float64) (ans float64) { d1 := build(pairs1, rates1, initialCurrency) d2 := build(pairs2, rates2, initialCurrency) for currency, rate := range d2 { if val, found := d1[currency]; found { ans = max(ans, val/rate) } } return } func build(pairs [][]string, rates []float64, init string) map[string]float64 { g := make(map[string][]Pair) d := make(map[string]float64) for i := 0; i < len(pairs); i++ { a := pairs[i][0] b := pairs[i][1] r := rates[i] g[a] = append(g[a], Pair{Key: b, Value: r}) g[b] = append(g[b], Pair{Key: a, Value: 1.0 / r}) } dfs(g, d, init, 1.0) return d } func dfs(g map[string][]Pair, d map[string]float64, a string, v float64) { if _, found := d[a]; found { return } d[a] = v for _, pair := range g[a] { b := pair.Key r := pair.Value if _, found := d[b]; !found { dfs(g, d, b, v*r) } } }
-
class Pair { constructor( public key: string, public value: number, ) {} } function maxAmount( initialCurrency: string, pairs1: string[][], rates1: number[], pairs2: string[][], rates2: number[], ): number { const d1 = build(pairs1, rates1, initialCurrency); const d2 = build(pairs2, rates2, initialCurrency); let ans = 0; for (const [currency, rate] of Object.entries(d2)) { if (currency in d1) { ans = Math.max(ans, d1[currency] / rate); } } return ans; } function build(pairs: string[][], rates: number[], init: string): { [key: string]: number } { const g: { [key: string]: Pair[] } = {}; const d: { [key: string]: number } = {}; for (let i = 0; i < pairs.length; ++i) { const a = pairs[i][0]; const b = pairs[i][1]; const r = rates[i]; if (!g[a]) g[a] = []; if (!g[b]) g[b] = []; g[a].push(new Pair(b, r)); g[b].push(new Pair(a, 1 / r)); } dfs(g, d, init, 1.0); return d; } function dfs( g: { [key: string]: Pair[] }, d: { [key: string]: number }, a: string, v: number, ): void { if (a in d) { return; } d[a] = v; for (const pair of g[a] || []) { const b = pair.key; const r = pair.value; if (!(b in d)) { dfs(g, d, b, v * r); } } }