異なる金種と合計金額のコインが与えられます。合計金額を構成できるコインの組み合わせの数を計算する関数を記述します。各宗派の無限のコインがあると仮定します。
例1:
入力:金額= 5、コイン= [ 1、2、5 ]
出力:4
説明:合計金額を構成する方法は4つあります:
5 = 5
5 = 2 + 2 + 1
5 = 2 + 1 + 1 + 1
5 = 1 + 1 + 1 + 1 + 1出典:LeetCode
リンク:https ://leetcode-cn.com/problems/coin-change-2
方法1:動的プログラミング
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]
方法2:2次元配列を1次元配列に縮小する
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]
方法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]