📜  查找总和等于给定金额的最小数量的纸币和值(1)

📅  最后修改于: 2023-12-03 15:10:44.671000             🧑  作者: Mango

查找总和等于给定金额的最小数量的纸币和值

这是一个经典的面试题,在实际生活中也有很多应用场景,比如找零、货币兑换等。要求编写一个函数,输入一个总金额和一组纸币面额,输出最小数量的纸币和值,使其等于总金额。如果无法组成总金额,则返回 -1。

解法

该问题可以采用动态规划求解,具体思路如下:

  1. 定义状态:我们用 dp[i] 表示凑出金额 i 的最小数量,那么最终结果就是 dp[amount],其中 amount 是给定的总金额。

  2. 初始化:将 dp 数组全部初始化为无穷大,但 dp[0] = 0。因为凑出金额为 0 需要 0 张纸币。

  3. 状态转移:对于每种面额的纸币,我们可以选择使用或者不使用,因此状态转移方程为:

    dp[i] = min(dp[i], dp[i - coins[j]] + 1)
    

    其中 coins[j] 表示第 j 种纸币面额,i - coins[j] 表示在不使用当前面额的情况下,凑出剩余金额的最小数量,然后加上当前面额的一张纸币,就可以得到凑出金额 i 的最小数量。

  4. 返回值:如果最终的答案为无穷大,则说明无法组成总金额,返回 -1。

代码实现

下面是使用 Python 语言实现的代码:

def coinChange(coins, amount):
    dp = [float('inf')] * (amount + 1)
    dp[0] = 0

    for i in range(1, amount + 1):
        for j in range(len(coins)):
            if i - coins[j] >= 0:
                dp[i] = min(dp[i], dp[i - coins[j]] + 1)

    return dp[amount] if dp[amount] != float('inf') else -1

该函数的时间复杂度为 $O(nm)$,其中 n 是总金额,m 是纸币的种类数。空间复杂度为 $O(n)$。