322. 零钱兑换 - medium
给定不同面额的硬币 coins
和一个总金额 amount
。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins =[1, 2, 5]
, amount =11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins =[2]
, amount =3
输出:-1
示例 3:
输入:coins = [1], amount = 0 输出:0
示例 4:
输入:coins = [1], amount = 1 输出:1
示例 5:
输入:coins = [1], amount = 2 输出:2
提示:
1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104
设 f(n) 表示总和为 n 所需最少硬币数。直接暴力计算会超时。可以通过 cache 数组缓存 f(n) 结果。
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
cache = [0] * (amount + 1)
def f(n: int) -> int:
if n == 0:
return 0
elif n < 0:
return -1
if cache[n] != 0:
return cache[n]
i = -1
for c in coins:
v = f(n - c)
if v >= 0 and (i == -1 or v < i):
i = v + 1
cache[n] = i
return i
return f(amount)
用 dp[i]
表示和为 i 时,需要的最小硬币数。
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [0] + [float('inf')] * amount
for c in coins:
for i in range(c, amount + 1):
dp[i] = min(dp[i], dp[i - c] + 1)
return dp[-1] if dp[-1] != float('inf') else -1