1、题目
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
说明:
你可以认为每种硬币的数量是无限的。
2、解题思路
定义 DP(i) 为组成金额 i 所需最少的硬币数量
DP(i) | 最小硬币数量 |
---|---|
DP(0) | 0 //金额为0不能由硬币组成 |
DP(1) | 1 //F(1)=min(F(1-1),F(1-2),F(1-5))+1=1F(1)=min(F(1−1),F(1−2),F(1−5))+1=1 |
DP(2) | 1 //F(2)=min(F(2-1),F(2-2),F(2-5))+1=1F(2)=min(F(2−1),F(2−2),F(2−5))+1=1 |
DP(3) | 2 //F(3)=min(F(3-1),F(3-2),F(3-5))+1=2F(3)=min(F(3−1),F(3−2),F(3−5))+1=2 |
DP(4) | 2 //F(4)=min(F(4-1),F(4-2),F(4-5))+1=2F(4)=min(F(4−1),F(4−2),F(4−5))+1=2 |
… | … |
DP(11) | 3 //F(11)=min(F(11-1),F(11-2),F(11-5))+1=3F(11)=min(F(11−1),F(11−2),F(11−5))+1=3 |
3、代码:
class Solution {
public int coinChange(int[] coins, int amount) {
int res = 0;
int[] dp = new int[amount + 1];
for(int i = 0; i <= amount; i ++){
dp[i] = amount + 1;
}
dp[0] = 0;
for(int i = 1; i <= amount; i++){
for(int coin : coins){
if(i < coin){
continue;
}
dp[i] = Math.min(1 + dp[i-coin], dp[i]);
}
}
return (dp[amount] == amount + 1) ? -1 : dp[amount];
}
}