LeetCode322. 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

你可以认为每种硬币的数量是无限的。

输入:coins = [1, 2, 5], amount = 11
输出:3 
解释:11 = 5 + 5 + 1
var coinChange = function(coins, amount) {
    // 如果amount为0,则直接return 0即可
    if(amount===0) return 0;
    //创建dp数组用于记录已经计算过的子问题,因为硬币最小面额为1,最坏的情况也是amount个硬币就可以凑出amount金额,所以将数组中的元素都填充为amount+1,相当于初始化为最大值
    let dp = new Array(amount+1).fill(amount+1);
    // dp的下标代表当前amount的值,dp[0]就代表amount为0的情况,不需要硬币即可凑出
    dp[0] = 0;
    从dp1开始遍历,依次尝试不同面值的硬币组成i所需要的硬币个数
    for(let i=1;i<=amount;i++) {
        for(let j=0;j<coins.length;j++) {
            // 当前硬币面值小于i的时候再去调用状态转移方程
            if(coins[j]<=i) {
                dp[i] = Math.min(dp[i],dp[i-coins[j]]+ 1)
            }
        }
    }
    // 如果最终求出的amount需要硬币个数小于amount本身,则可以凑出,否则无法根据现有的硬币面值凑出,根据题意return -1
    return dp[amount] <=amount ? dp[amount] : -1;
};

 

posted @ 2021-04-06 10:53  JMH0113  阅读(72)  评论(0)    收藏  举报