leetcode 322零钱兑换 动态规划 Java

题目描述

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

示例 1:

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

解题思路:

  • dp[i]代表金额i的最优解,即使用最少张数,使用dp[1]~dp[amount]存储1-amount金额的最优解
  • 实例中金额分别1,2,5.所以dp[1],dp[2],dp[5]都是等于1
  • 金额i最优解可以由i-1与dp[1],i-2与dp[2],i-5与dp[5]转移得到,所以dp[i]的最优解就是dp[i-1]+1,dp[i-2]+1,dp[i-5]+1中最小的。
  • 转移方程dp[i]=min(dp[i-coins[j]]+1)
  • 初始化dp[0]=0
class Solution {
    public int coinChange(int[] coins, int amount) {
        int[] dp=new int[amount+1];
        for(int i=0;i<=amount;i++){
            dp[i]=-1;//初始化dp[],用-1标记为不可达
        }
        dp[0]=0;//初始化边界条件
        for(int i=1;i<=amount;i++){
            for(int j=0;j<coins.length;j++){
                if(i-coins[j]>=0&&dp[i-coins[j]]!=-1){//当前金额-面值>0&&前面差值可达、可表示
                    if(dp[i]==-1||dp[i]>dp[i-coins[j]])//dp[i]没被更新过或者dp[i]有更好的解
                        dp[i]=dp[i-coins[j]]+1;
                }
            }
        }
        return dp[amount];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值