Given coins of different denominations and a total amount. Write a function to calculate the number of coin combinations that can make up the total amount. Suppose there are infinite coins of each denomination.
Example 1:
Input: amount = 5, coins = [1, 2, 5]
Output: 4
Explanation: There are four ways to make up the total amount:
5=5
5=2+2+1
5=2+1+1+1
5 =1+1+1+1+1Source: LeetCode
Link: https://leetcode-cn.com/problems/coin-change-2
Method 1: Dynamic programming
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
coin_len=len(coins)
dp=[ [0 for _ in range(amount+1)] for _ in range(coin_len+1) ]
for i in range(coin_len+1):
dp[i][0]=1
# 扫描全部coins和amount的组合
for i in range(1,coin_len+1):
for j in range(1,amount+1):
# 如果你不把这第 i 个物品装入背包,也就是说你不使用 coins[i] 这个面值的硬币,
# 那么凑出面额 j 的方法数 dp[i][j] 应该等于 dp[i-1][j],继承之前的结果。
# 如果你把这第 i 个物品装入了背包,也就是说你使用 coins[i] 这个面值的硬币,那
# 么 dp[i][j] 应该等于 dp[i][j-coins[i-1]]
#
if j-coins[i-1]>=0:
dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]]
else:
dp[i][j]=dp[i-1][j]
return dp[coin_len][amount]
Method 2: Shrink a two-dimensional array into a one-dimensional array
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
coin_len=len(coins)
# 压缩两维数组为1维数组
dp=[0 for _ in range(amount+1)]
dp[0]=1
for i in range(0,coin_len):
for j in range(1,amount+1):
if (j-coins[i-1])>=0:
dp[j]=dp[j]+dp[j-coins[i-1]]
return dp[amount]
Method 3:
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
coin_len=len(coins)
# 特殊条件判断
if amount == 0:
return 1
# 根据Python特性重新构建新的迭代关系,并修改原有的状态转移公式
dp = [0] * (amount + 1)
dp[0] = 1
for coin in coins:
for i in range(coin, amount + 1):
dp[i] = dp[i] + dp[i - coin]
return dp[amount]