【发布时间】:2020-03-14 09:45:33
【问题描述】:
我在 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))。正确答案是什么?
我似乎在递归函数中遇到了很多循环,有时我们似乎将它们计算在时间复杂度中,而其他时候它们已经在子问题中“定价”了,就像我怀疑这里的情况一样。
【问题讨论】:
-
你的分析对我来说似乎是正确的。您的表格中有 O(amount * number of coin) 单元格,并且要计算表格中的任何单元格,您需要运行一个循环(硬币数量)次。您编写的代码具有这种复杂性。很可能存在具有 O(数量 * 硬币数量)复杂度的不同算法。
标签: algorithm recursion time-complexity memoization coin-change