零钱兑换一是个相对简单的DP问题,其题面为
给定一个整数数组 coins ,表示N种不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
实例:
输入:coins = {1, 2, 5}, amount = 11
输出:3
解释:11 = 5 + 5 + 1
解题思路在于首先定义一个F(k)函数,k是[1,amount]之间的整数,该函数返回的是金额为k时所需最少的硬币数量,对于给定的N种硬币,我们可以看出
F(k)
= amount + 1, k < 0
= 0, k = 0
= min of (1 + F(k - coin[0]), 1 + F(k - coin[1]) ... 1 + F(k - coin[N - 1]))
F(k)的边界情况为当k < 0时,返回amount + 1,因为没有任何组合可以凑成一个负数的金额,使用amount + 1以代表这种不可能的情况,
根据以上的表达式,我们可以使用一个一维数组作为DP存储,并依据k的数值从小到大依次计算DP数组种的各个元素,最后DP[amount]中的数据就是给定问题的答案。
Java代码如下
class Solution {
public int coinChange(int[] coins, int amount) {
if (amount == 0) {
return 0;
}
int N = coins.length;
int[] dp = new int[amount + 1];
for (int k = 1; k<= amount; k ++) {
int min = amount + 1;
for (int j = 0; j < N; j ++) {
if (k >= coins[j]) {
int n = 1 + dp[k - coins[j]];
min = Math.min(min, n);
}
}
dp[k] = min;
}
if (dp[amount] > amount) {
return -1;
} else {
return dp[amount];
}
}
}