最朴素的版本
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
n = len(coins)
if n <= 0 or amount < 0: return -1
d = [[float('inf')] * (amount + 1) for _ in range(n)]
d[0][0] = 0
## 如果需要兑换的钱为0,则不需要硬币
for i in range(n): d[i][0] = 0
## 第一行初始化 反复取第一枚硬币所能满足的amount
for j in range(1, amount + 1):
d[0][j] = float('inf')
if j - coins[0] >= 0 and d[0][j - coins[0]] != float('inf'):
d[0][j] = d[0][j - coins[0]] + 1
# print('debug-1', d)
for i in range(1, n):
# for j in range(1, amount + 1): ## 步涌每个都遍历 这个也是进阶版不是原始
for j in range(1, amount+1):
k = 0
while k*coins[i] <= j :
d[i][j] = min(d[i][j], d[i-1][j-k*coins[i]]+k)
k += 1
# print('debug-2',d)
return d[-1][-1] if d[-1][-1] != float('inf') else -1
优化后版本1
class Solution:
def minMoney(self , arr , aim ):
# write code here
n = len(arr)
if n<=0 or aim <0: return -1
d = [[float('inf')] * (aim + 1) for _ in range(n)]
d[0][0] = 0
## 如果需要兑换的钱为0,则不需要硬币
for i in range(n):
d[i][0] = 0
## 第一行初始化 反复取第一枚硬币所能满足的aim
for j in range(1, aim+1):
d[0][j] = float('inf')
if j - arr[0] >=0 and d[0][j-arr[0]] !=float('inf'):
d[0][j] = d[0][j-arr[0]] + 1
for i in range(1, n):
for j in range(1, aim + 1):
left = float('inf')
if j- arr[i] >=0 and d[i][j-arr[i]] != float('inf'):
left = d[i][j - arr[i]] + 1
d[i][j] = min(d[i-1][j], left)
return d[-1][-1] if d[-1][-1] != float('inf') else -1
二维转一维优化
class Solution(object):
def coinChange(self, coins, amount):
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for coin in coins:
for x in range(coin, amount + 1):
dp[x] = min(dp[x], dp[x - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
回溯版本 => 记忆化搜索 => 二维表 =>滚动数组
无限放取+方法数
arr里都是正数,没有重复,每一个值代表一种货币,每一种都可以用无限张,最终要找零钱是aim,
找零方法数放回
递归 入参 process(arr, index, rest)
自由使用arr[index…] 所有的面值
需要搞定的钱数rest
返回找零的方法数
终止条件,决定dp表的一些初始位置,非常重要
if index == arr.length:
resturn rest == 1 if rest==0 else 0
递归方程
way = 0
zhang = 0
while arr[index] * zhang <= rest:
ways += process(arr, index+1, rest-arr[indext]*zhang)
zhang += 1
return way
只能取一次,最少的零钱数量返回
终止条件:
if rest <0: return -1
if rest=0: return 0
if index == length: return -1
一般情况:
p1= process( arr, index+1, rest)
p2 = process(arr, index+1, rest - arr[index])
if (p1== -1 and p2==-1):
return -1
else:
if p1==-1:
return p2+1
if p2==-1:
return p1
return min(p1, p2+1)
969

被折叠的 条评论
为什么被折叠?



