Article directory
1. Violent recursion
coinChange([1,2,5], 11) = 1 + min( coinChange([1,2,5], 10), coinChange([1,2,5], 9, coinChange([1,2,5 ], 6) )
import sys
class Solution:
def coinChange(self, coins: [], amount: int) -> int:
if amount == 0:
return 0
if amount < 0:
return -1
res = sys.maxsize
for coin in coins:
# 计算子问题的结果
subProblem = self.coinChange(coins, amount - coin)
# 子问题无解则跳过
if subProblem == -1:
continue
# 在子问题中选最优解,然后+1
res = min(res, subProblem + 1)
if res == sys.maxsize:
return -1
else:
return res
if __name__ == '__main__':
coins = [1, 2, 5]
amount = 11
x = Solution().coinChange(coins, amount)
print(x)
2. Recursion with memo
However, the above violent recursion has repeated calculation, such as coinChange(coins, 9) corresponding to the yellow square in the above figure is repeated.
import sys
class Solution:
def coinChange(self, coins: [], amount: int) -> int:
memo = [-666 for i in range(0, amount+1)] # 赋初值,用于区分未计算的,还是计算过但值为0的
return self.helper(coins, amount, memo)
def helper(self, coins: [], amount: int, memo: []) -> int:
if amount == 0:
return 0
if amount < 0:
return -1
if memo[amount] != -666:
return memo[amount]
res = sys.maxsize
for coin in coins:
# 计算子问题的结果
subProblem = self.helper(coins, amount - coin, memo)
# 子问题无解则跳过
if subProblem == -1:
continue
# 在子问题中选最优解,然后+1
res = min(res, subProblem + 1)
memo[amount] = res
if res == sys.maxsize:
return -1
else:
return res
if __name__ == '__main__':
coins = [1, 2, 5]
amount = 11
x = Solution().coinChange(coins, amount)
print(x)
Since the time complexity of recursion is equal to the number of recursion (N times) times the complexity inside the recursive function (O(k)), the time complexity is O(k * N).
3. Dynamic programming
The iterative process from bottom to top is as follows:
class Solution:
def coinChange(self, coins: [], amount: int) -> int:
dp = [amount + 1 for i in range(0, amount+1)]
dp[0] = 0
for a in range(0, amount+1):
for coin in coins:
if coin > a:
continue
dp[a] = min(dp[a], dp[a-coin]+1)
if dp[amount] == amount + 1:
return -1
return dp[amount]
if __name__ == '__main__':
coins = [2]
amount = 3
x = Solution().coinChange(coins, amount)
print(x)