前言
本题主要考查 动态规划 算法。
提示:以下是本篇文章正文内容,编程语言为Java
一、题目描述
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
链接:零钱兑换
二、解题思路
1)确定dp数组的含义。 我们用 dp[i]
表示总金额为 i
时所需的最少的硬币个数。
2)推导状态转移方程。 总金额达到了 i
,是因为我们总金额 i-j
时又兑换了一个面额 j
的硬币。所以上一个状态对应 dp[i-j]
,我们要枚举所有的面额 j
,选择其中需要硬币数最少的。同时要考虑硬币不能组合成总金额的情况,因此枚举 dp[i]
时需要初始化一个比较大的值。
三、示例代码
class Solution {
public int coinChange(int[] coins, int amount) {
if(amount==0) return 0;
Arrays.sort(coins);
int step=coins[0];
if(coins[0]>amount) return -1;
int []dp=new int[amount+1];
dp[0]=0;
int i;
for(i=1;i<=amount;i++){
dp[i]=10005;
for(int j=0;j<coins.length;j++){
if(i-coins[j]>=0){
dp[i]=Math.min(dp[i],dp[i-coins[j]]+1);
}
}
}
return dp[amount]==10005?-1:dp[amount];
}
}