📜  硬币找零 2 (1)

📅  最后修改于: 2023-12-03 14:56:31.009000             🧑  作者: Mango

硬币找零2
简介

硬币找零问题是一种经典的动态规划问题,它的目的是在一个给定的金额下,找出最少的硬币数来凑出这个金额。

硬币找零2问题是在硬币找零问题的基础上加上了硬币的数量限制,在某些情况下,硬币的数量是有限制的,那么就需要找出在限制硬币的数量下能够凑出给定金额的最小硬币数。

算法思路

与硬币找零1问题类似,硬币找零2问题也可以采用动态规划的思想来求解。假设现有硬币面值为coins=[c1,c2,...,cn],下面给出详细的算法思路。

  1. 初始化一个长度为amount+1的数组dp,并将dp[0]设置为0。

  2. 遍历硬币数组 coins,对于每个硬币面值 ci,进行如下操作:

    1. 从面值 ci 开始遍历数组 dp,对于数组中的每个元素 dp[j],如果 j≥ci 且 dp[j−ci]≠−1,则更新 dp[j] 的值,使其等于 dp[j−ci]+1。此时,这个元素的值就表示凑出金额 j 所需的最小硬币数量。

    2. 如果遍历完数组 dp 后,dp[amount] 的值仍然为初始值 -1,那么说明无法凑出给定金额,此时返回 0。

  3. 最后返回数组 dp[amount] 的值,就是凑出给定金额所需的最小硬币数量。

代码实现

下面是 Python 语言的实现代码。

def coinChange(coins, amount):
    dp = [-1] * (amount + 1)
    dp[0] = 0
    for coin in coins:
        for j in range(coin, amount + 1):
            if dp[j - coin] != -1:
                if dp[j] == -1:
                    dp[j] = dp[j - coin] + 1
                else:
                    dp[j] = min(dp[j], dp[j - coin] + 1)
    return dp[amount]
时间与空间复杂度分析

该算法中使用了一个长度为 amount+1 的数组 dp,同时对于每个硬币面值 ci,需要从 ci 开始遍历数组 dp,因此算法的时间复杂度为 O(amount×n),其中 n 是硬币的种类数。

而数组 dp 占用的空间为 O(amount+1),因此,算法的空间复杂度为 O(amount)。

总结

硬币找零2问题是硬币找零问题的一种扩展形式,它是一种经典的动态规划问题。该问题可以通过动态规划的思想来求解,其算法思路就是遍历硬币数组,对于每个硬币面值 ci,从 ci 开始遍历数组 dp,对于数组中的每个元素 dp[j],如果 j ≥ ci 且 dp[j−ci] ≠ −1,则更新 dp[j] 的值,使其等于 dp[j−ci]+1。最后返回数组 dp[amount] 的值,就是凑出给定金额所需的最小硬币数量。

该算法的时间复杂度为 O(amount×n),其中 n 是硬币的种类数,空间复杂度为 O(amount)。