凑零钱问题
题⽬ :
给你 k 种⾯值的硬币, ⾯值分别为 c1, c2 … ck , 每种硬
币的数量⽆限, 再给⼀个总⾦额 amount , 问你最少需要⼏枚硬币凑出这个
⾦额, 如果不可能凑出, 算法返回 -1。
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 3 14:14:19 2021
@author: dujidan
"""
from collections import defaultdict
# 递归
def coinChange(coins, amount):
def dp(n):
#base case
if n == 0:
return 0
if n < 0:
return -1
#求最小值, 所以初始化为正无穷
res = float('inf')
for coin in coins:
subproblem = dp(n - coin)
if subproblem == -1:
continue
res = min([res, 1 + subproblem])
return res if res != float('inf') else -1
return dp(amount)
# 递归 备忘录
def coinChange(coins, amount):
meno = {}
def dp(n):
# 备忘录 避免重复计算
if n in meno:
return meno[n]
# base case
if n == 0:
return 0
if n < 0:
return -1
# 求最小值, 所以初始化为正无穷
res = float('inf')
for coin in coins:
subproblem = dp(n - coin)
if subproblem == -1:
continue
res = min([res, 1 + subproblem])
meno[n] = res if res != float('inf') else -1
return meno[n]
return dp(amount)
# 数组的迭代解法
def coinChange(coins, amount):
dp = defaultdict(int)
dp[0] = 0
for i in range(1, amount + 1):
dp[i] = amount + 1
for coin in coins:
if i - coin < 0:
continue
dp[i] = min([dp[i], 1 + dp[ i - coin]])
return ( -1 if dp[amount] == -1 else dp[amount])
coins = [1, 3, 5]
amount = 11
print(coinChange(coins, amount))
参考:labuladong 公众号