如何解决具有传递性dependencies/graphs的算法题?

How to solve algorithmic questions with transitive dependencies/graphs?

当我在面试中被问到这些问题时,我有点挣扎。举例来说,我有一个问题,我需要找到从一种货币转换为另一种货币的货币金额,并且我得到了货币列表。如何构建 adjacency/relationship 映射以便我可以获得正确的数量。即使是解释逻辑的算法也足够了。感谢您对此的建议!

例如:

假设我得到了一个货币对象列表,其中包含不同的转换率(USD->INR = 75,INR -> XXX = 100)。我需要找到从 USD-> XXX = 7500 的转换。我也应该能够向后转换,比如 INR->USD。如何通过构建图表找到它?.

public Currency{
String fromCurrency;
String toCurrency;
double rate;
}

public double currencyConverter(List<Currency> currencies, fromCurrency, toCurrency){

return convertedCurrency;
}

在你提到的问题中,图是有向图。假设您使用邻接矩阵表示图形。用您拥有的所有货币数据填充矩阵。例如,USD->INR 的汇率为 R1,因此 INR->USD 的汇率为 1/R1。填充邻接矩阵后,使用algorithms to compute transitive closure of a directed graph, for example Floyd–Warshall algorithm.

我不确定如何使用 Floyd-Warshall 算法来解决这个问题。但是,我能够使用动态编程解决这个问题。这是我的解决方案:

class Currency{

    String fromCurrency;
    String toCurrency;
    double rate;

    public Currency(String fromCurrency, String toCurrency, double rate) {
        this.fromCurrency = fromCurrency;
        this.toCurrency = toCurrency;
        this.rate = rate;
    }
}

public class CurrencyConverter {

    public static double currencyConverter(List<Currency> currencies, String fromCurrency, String toCurrency) {

        Set<String> currencyNotes = new LinkedHashSet<>();

        for(Currency currency : currencies) {
            currencyNotes.add(currency.fromCurrency);
            currencyNotes.add(currency.toCurrency);
        }

        Map<String, Integer> currencyMap = new TreeMap<>();
        int idx = 0;

        for(String currencyNote : currencyNotes) {
            currencyMap.putIfAbsent(currencyNote, idx++);
        }

        double[][] dp = new double[currencyNotes.size()][currencyNotes.size()];

        for(double[] d : dp) {
            Arrays.fill(d, -1.0);
        }

        for(int i=0;i<currencyNotes.size();i++) {
            dp[i][i] = 1;
        }

        for(Currency currency : currencies) {
            Integer fromCurrencyValue = currencyMap.get(currency.fromCurrency);
            Integer toCurrencyValue = currencyMap.get(currency.toCurrency);

            dp[fromCurrencyValue][toCurrencyValue] = currency.rate;
            dp[toCurrencyValue][fromCurrencyValue] = 1/(currency.rate);
        }

        for(int i=currencyNotes.size()-2;i>=0;i--) {
            for(int j= i+1;j<currencyNotes.size();j++) {
                dp[i][j] = dp[i][j-1]*dp[i+1][j]/(dp[i+1][j-1]);
                dp[j][i] = 1/dp[i][j];
            }
        }

        return dp[currencyMap.get(fromCurrency)][currencyMap.get(toCurrency)];

    }

我认为解决传递依赖问题的最好方法是首先识别节点及其关系,然后回溯。正如黑暗骑士的小丑所说 "Sometimes all it takes is a little push" :)