前端算法-零钱兑换

934 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第45天,点击查看活动详情

题目

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

输入: coins = [1, 2, 5], amount = 11
输出: 3 
解释: 11 = 5 + 5 + 1

思路一

我们这里先判断一下当前的形参amount是否为0,如果为0则直接将形参amount返回出去,如果不是我们在判断形参coins长度是否为0,如果为0则直接返回-1,我们接下来创建一个arr数组,用于记录面额从1到amount的最少硬币数,数组长度为amount+1是为了让数组的下标能直观的对应面额,然后将arr数组的首个位置默认为0,接下来使用循环,记录总金额从1到amount的最少组合次数,在循环中我们在使用一层循环进行遍历能组合的面额,在第二层循环中我们判断当前总金额是否大于等于当前循环中的面额,如果是则说明能组合,能组合的情况下我们就使用Math.min方法在已知最少组合数和当前组合最少数获取到组少组合,赋值给arr数组中的i变量数据,当循环结束后,我们判断如果arr数组中的总金额小于coins中的所有面额,那么对应的元素就一直是Infinity,我们就直接返回-1,否则我们将总金额返回出去即可

var coinChange = function(coins, amount) {
    if(amount === 0) {
        return amount
    }
    if(coins.length === 0) {
        return -1
    }
    let arr = new Array(amount+1).fill(Infinity)
    arr[0] = 0
    for(let i=1;i<=amount;i++){
        for(let j=0,len=coins.length;j<len;j++){
            if(i>=coins[j]){
                arr[i] = Math.min(arr[i],arr[i-coins[j]]+1)
            }
        }
    }
    if(arr[amount] === Infinity){
        return -1;
    }else{
       return arr[amount];
    }
};