给你一个整数数组 coins
,表示不同面额的硬币;以及一个整数 amount
,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1
。
你可以认为每种硬币的数量是无限的。
class Solution {
public int coinChange(int[] coins, int amount) {
// 创建一个数组 dp,用于存储计算过程中的结果,dp[i] 表示凑成金额 i 所需要的最少硬币数量
int[] dp = new int[amount + 1];
// 初始化一个最大值,用于表示不可能达到的情况
int max = Integer.MAX_VALUE;
// 初始化数组 dp 的所有元素为最大值,表示初始情况下,凑成各个金额的硬币数量均为不可能的最大值
for (int i = 0; i < dp.length; i++) {
dp[i] = max;
}
// 凑成金额 0 所需的最少硬币数量为 0
dp[0] = 0;
// 外层循环遍历硬币数组中的每种硬币
for (int i = 0; i < coins.length; i++) {
// 内层循环从当前硬币的面值开始遍历,直到目标金额 amount
for (int j = coins[i]; j <= amount; j++) {
// 判断是否可以用当前硬币凑成金额 j
if (dp[j - coins[i]] != max) {
// 选择硬币数目最小的情况
dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
}
}
}
// 返回凑成目标金额 amount 所需要的最少硬币数量,如果无法凑成,则返回 -1
return dp[amount] == max ? -1 : dp[amount];
}
}