Python兑换零钱
引言
在现实生活中,我们经常会遇到需要兑换零钱的情况,比如去超市购物后需要找零钱。而对于商家来说,通常会尽量使用较少数量的硬币/纸币来找零,以便降低找零的成本。在这种情况下,我们可以使用Python来解决这个问题。
本文将介绍一个使用动态规划算法解决兑换零钱问题的Python代码示例,并使用序列图来说明算法的执行过程。
动态规划算法
动态规划算法是一种通过拆分问题为更小的子问题,并通过子问题的解来解决原问题的方法。对于兑换零钱的问题,我们可以将其拆解为一个个子问题,每个子问题表示兑换一定金额的零钱所需的最少硬币数量。
假设我们有一组硬币面额为 [1, 2, 5]
,需要兑换金额为 11
的零钱。我们可以定义一个长度为 12
的列表 dp
,其中 dp[i]
表示兑换金额为 i
的零钱所需的最少硬币数量。初始时,我们将列表中的所有元素设为一个较大的数,以便后续比较取最小值。
代码示例
下面是使用动态规划算法解决兑换零钱问题的Python代码示例:
def coinChange(coins, amount):
# 初始化dp列表
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for i in range(1, amount + 1):
for coin in coins:
if i - coin >= 0:
dp[i] = min(dp[i], dp[i - coin] + 1)
if dp[amount] == float('inf'):
return -1
else:
return dp[amount]
coins = [1, 2, 5]
amount = 11
print(coinChange(coins, amount))
在上述代码中,我们首先定义了一个 coinChange
函数,它接受两个参数:coins
和 amount
。coins
是一个整数列表,表示可用的硬币面额,amount
是需要兑换的金额。
函数开始时,我们初始化一个长度为 amount + 1
的 dp
列表,将其中的所有元素设为一个较大的数(这里使用 float('inf')
表示正无穷大)。然后,我们将 dp[0]
初始化为 0
,表示兑换金额为 0
的零钱所需的最少硬币数量为 0
。
接下来,我们使用两层循环遍历所有金额(从 1
到 amount
)和可用的硬币面额。对于每个金额 i
,我们尝试使用每个硬币面额 coin
进行兑换,并更新 dp[i]
的值为 dp[i - coin] + 1
的最小值。
最后,我们检查 dp[amount]
的值是否为正无穷大。如果是,则表示无法兑换金额为 amount
的零钱;如果不是,则返回 dp[amount]
,即兑换金额为 amount
的零钱所需的最少硬币数量。
在上述代码的最后,我们使用了一个例子来演示函数的使用,将 coins
设置为 [1, 2, 5]
,amount
设置为 11
,并打印出结果。
序列图
下面是使用mermaid语法绘制的序列图,说明了动态规划算法在兑换零钱问题中的执行过程:
sequenceDiagram
participant User
participant Program
User->>Program: 提供硬币面额和兑换金额
Program->>Program: 初始化dp列表
Program->>Program: 设定初始值
Program->>Program: 开始动态规划
Program->>Program: 更新dp列表
Program->>Program: 返回兑换