LeetCode in Kotlin

3387. Maximize Amount After Two Days of Conversions

Medium

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):

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:

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:

Solution

import kotlin.math.max

class Solution {
    private var res = 0.0
    private var map1: MutableMap<String, MutableList<Pair>>? = null
    private var map2: MutableMap<String, MutableList<Pair>>? = null

    private class Pair(var tarcurr: String, var rate: Double)

    private fun solve(
        currCurrency: String,
        value: Double,
        targetCurrency: String?,
        day: Int,
        used: MutableSet<String?>,
    ) {
        if (currCurrency == targetCurrency) {
            res = max(res, value)
            if (day == 2) {
                return
            }
        }
        val list: MutableList<Pair> = if (day == 1) {
            map1!!.getOrDefault(currCurrency, ArrayList<Pair>())
        } else {
            map2!!.getOrDefault(currCurrency, ArrayList<Pair>())
        }
        for (p in list) {
            if (used.add(p.tarcurr)) {
                solve(p.tarcurr, value * p.rate, targetCurrency, day, used)
                used.remove(p.tarcurr)
            }
        }
        if (day == 1) {
            solve(currCurrency, value, targetCurrency, day + 1, HashSet<String?>())
        }
    }

    fun maxAmount(
        initialCurrency: String,
        pairs1: List<List<String>>,
        rates1: DoubleArray,
        pairs2: List<List<String>>,
        rates2: DoubleArray,
    ): Double {
        map1 = HashMap<String, MutableList<Pair>>()
        map2 = HashMap<String, MutableList<Pair>>()
        var size = pairs1.size
        for (i in 0..<size) {
            val curr = pairs1[i]
            val c1 = curr[0]
            val c2 = curr[1]
            if (!map1!!.containsKey(c1)) {
                map1!!.put(c1, ArrayList<Pair>())
            }
            map1!![c1]!!.add(Pair(c2, rates1[i]))
            if (!map1!!.containsKey(c2)) {
                map1!!.put(c2, ArrayList<Pair>())
            }
            map1!![c2]!!.add(Pair(c1, 1.0 / rates1[i]))
        }
        size = pairs2.size
        for (i in 0..<size) {
            val curr = pairs2[i]
            val c1 = curr[0]
            val c2 = curr[1]
            if (!map2!!.containsKey(c1)) {
                map2!!.put(c1, ArrayList<Pair>())
            }
            map2!![c1]!!.add(Pair(c2, rates2[i]))
            if (!map2!!.containsKey(c2)) {
                map2!!.put(c2, ArrayList<Pair>())
            }
            map2!![c2]!!.add(Pair(c1, 1.0 / rates2[i]))
        }
        res = 1.0
        solve(initialCurrency, 1.0, initialCurrency, 1, HashSet<String?>())
        return res
    }
}