题目描述
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3
输出:-1
示例 3:
输入:coins = [1], amount = 0
输出:0
提示:
1 <= coins.length <= 12
1 <= coins[i] <= 231 - 1
0 <= amount <= 104
代码
class Solution {
public int coinChange(int[] coins, int amount) {
//注意这个题目是硬币有无限个,所以是完全背包问题
//因为递推公式需要判断哪种方法硬币更少,也就会用到math.min()
// 如果初始化为0的话最后结果肯定都是0,所以要找个最大的数值来不断更新最小值
int max = Integer.MAX_VALUE;
int[] dp =new int[amount+1];
for (int j = 0; j <=amount; j++) {
dp[j] = max;
}
//0的时候不需要硬币找
dp[0]=0;
for (int i = 0; i <coins.length; i++) {
for (int j = coins[i]; j <=amount ; j++) {
if (dp[j-coins[i]]!=max){
//分两种情况,一种是不加入当前硬币找零需要多少个,第二种是减去当前硬币的值的个数加上当前这一个硬币
//哪种所需的硬币数少的话就用哪一种方式
dp[j] = Math.min(dp[j],dp[j-coins[i]]+1);
}
}
}
//如果没有更新过就证明找不开
if (dp[amount]==max){
return -1;
}
return dp[amount];
}
}