问题一 求组成目标金额的最小硬币数
解法一:递归
class Solution:
def __init__(self):
self.minn = float('inf')
def coinChange(self, coins, amount):
def Change(coins, num, rem):
if rem == 0:
self.minn = min(self.minn, num)
return
for coin in coins:
if rem >= coin:
Change(coins, num+1, rem-coin)
Change(coins, 0, amount)
if self.minn == float('inf'):
return -1
return self.minn
解法二:动态规划
class Solution:
def coinChange(self, coins, amount):
if amount == 0:
return 0
dp = [float('inf') for _ in range(amount+1)]
dp[0] = 0
for i in range(len(coins)):
for j in range(coins[i], amount+1):
dp[j] = min(dp[j], dp[j-coins[i]]+1)
if dp[amount] == float('inf'):
return -1
return dp[amount]
问题二 求组成目标金额的不同硬币数量
一、组合
硬币数组为外层循环。对于每一种硬币,遍历一遍dp数组。这样可以避免重复,即[1, 1, 2]
和[1, 2, 1]
的情况。
class Solution:
def change(self, amount, coins):
dp = [0 for _ in range(amount+1)]
dp[0] = 1
for coin in coins:
for j in range(coin, amount+1):
dp[j] += dp[j-coin]
return dp[amount]
二、排列
将遍历dp数组作为外层循环,遍历每一种硬币作为内层循环。
class Solution:
def change(self, amount, coins):
dp = [0 for _ in range(amount+1)]
dp[0] = 1
for j in range(amount+1):
for coin in coins:
if j >= coin:
dp[j] += dp[j-coin]
return dp[amount]