这种硬币找零算法的时间复杂度是多少?

时间:2019-11-18 23:30:07

标签: algorithm recursion time-complexity memoization coin-change

我解决了leetcode https://leetcode.com/problems/coin-change-2/上的硬币兑换问题。

这是我写的代码:

    def change(self, amount: int, coins: List[int]) -> int:
        def helper(amount, coins, ind):
            if amount == 0:
                return 1
            if amount < 0:
                return 0
            if (amount, ind) in dp:
                return dp[(amount, ind)]

            res = 0
            for i in range(ind, len(coins)):
                res  += helper(amount - coins[i], coins, i)

            dp[(amount, ind)] = res
            return res

        coins.sort()
        dp = {}
        return helper(amount, coins, 0)

我注意到我在用记忆分析算法的时间复杂性时非常费力。例如,在这种情况下,我认为我们有amount * number of coins个子问题->因此该算法在O(amount * number of coins * number of coins)中运行,我认为第二个硬币的原因是,对于每个子问题,我们都有遍历循环for i in range(ind, len(coins)):以累加结果。

但是,从我所阅读的内容来看,该解决方案实际上是O(amount * number of coins)(自底向上的方法是O(amount * number of coins))。正确的答案是什么?

我似乎在递归函数内部的循环上苦苦挣扎,有时好像我们把它们算在时间复杂度上,而有时它们已经在子问题中被“定价”了,我怀疑这里就是这种情况。

1 个答案:

答案 0 :(得分:0)

如Enrico Borba所说:

您的分析对我来说似乎是正确的。您的表中有O(amount * number of coins)个单元格,要计算表中的任何单元格,您需要运行一次循环(硬币数)。您编写的代码具有这种复杂性。可能存在另一种算法,其复杂度为O(数量*硬币数量)。

–恩里科·博尔巴(Enrico Borba)