leetCode: 322. 零钱兑换

原文地址: http://www.iming.top/details/5

给你 k 种面值的硬币,面值分别为 c1, c2 ... ck,每种硬币的数量无限

再给一个总金额 amount,问你最少需要几枚硬币凑出这个金额,如果不可能凑出,算法返回 -1 。

function coinChange(coins, amount) {

    const dp = []
    for (let i = 0; i <= amount; i++) {
        dp.push(Infinity)
    }

    dp[0] = 0

    for (let i = 1; i <= amount; i++) {
        for (let j = 0; j < coins.length; j++) {
            if (coins[j] > i) continue;
            
            const a = dp[i - coins[j]] + 1
            dp[i] = Math.min(dp[i], a)
        }
    }

    return dp[amount] === Infinity ? -1 : dp[amount]
}
console.log(coinChange([1,2,5] , 11))

 

分析如下:

想要凑够钱,使用最少的硬币,这里定义了一个数组

dp = [ Infinity,Infinity,Infinity,Infinity,Infinity,... ]

 

数组每一位都是无穷大,其实是占个位置,如果书其他的,最好还是number类型,因为后面使用了Math.min()函数

 

假设

coins = [1,2,5], amount = 11

 

如果在所选择的硬币当中含有1,那么总次数应该是 1 + dp(10)的最优解 如果在所选择的硬币当中含有2,那么总次数应该是 1 + dp(9)的最优解 如果在所选择的硬币当中含有5,那么总次数应该是 1 + dp(6)的最优解

 

问题就在组这里, 这时候我们不知道dp(10), dp(9)和dp(6)的最优解是什么

于是对于dp(10)来说:

如果在所选择的硬币当中含有1,那么总次数应该是 1 + dp(9)的最优解 如果在所选择的硬币当中含有2,那么总次数应该是 1 + dp(8)的最优解 如果在所选择的硬币当中含有5,那么总次数应该是 1 + dp(5)的最优解

 

以此类推,直到dp(0) 负数不考虑。而且dp里面是负数不会对数组造影响,因此我们只考虑到最后一个是dp(0)的情况

由上面的推断就可以得出来,我们需要求出0-amount每一位的最优值,因此有:

for (let i = 1; i <= amount; i++) { // 循环1-amount for (let j = 0; j < coins.length; j++) { // 看看选择不同的硬币后对比那个才是使用最少次数的。决定本轮的硬币的选择。 if (coins[j] > i) continue; const a = dp[i - coins[j]] + 1 dp[i] = Math.min(dp[i], a) } }

 

最终得到结果dp[amount]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值