LeetCode 322 & 518. 零钱兑换
LeetCode 322. 零钱兑换
原题链接
简介:给定不同面额的硬币 coins 和一个总金额 amount,计算可以凑成总金额所需的最少的硬币个数。如果不能凑成,返回 -1。
思路:动态规划
class Solution {
public int coinChange(int[] coins, int amount) {
if (amount == 0) {
return 0;
}
int[] dp = new int[amount + 1];
int max = amount + 1; // can't combine
for (int i = 1; i < dp.length; i++) {
dp[i] = max;
}
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (coin > i) {
continue;
}
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
return dp[amount] == max ? -1 : dp[amount];
}
}
LeetCode 322. 零钱兑换 II
简介:给定不同面额的硬币 coins 和一个总金额 amount,计算可以凑成总金额的不同组合数。
思路:动态规划,dp[i][j] 表示用前 i 种面额的硬币组成金额为 j 的不同组合数,转移方程 dp[i][j] = dp[i - 1][j] + dp[i][j - coin]。
class Solution {
public int change(int amount, int[] coins) {
if (coins.length * amount == 0) {
return amount == 0 ? 1 : 0;
}
int m = coins.length;
int[][] dp = new int[m + 1][amount + 1];
dp[0][0] = 1;
int coin;
for (int i = 1; i <= m; i++) {
coin = coins[i - 1];
dp[i][0] = 1;
for (int j = 1; j <= amount; j++) {
if (j < coin) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j] + dp[i][j - coin];
}
}
}
return dp[m][amount];
}
}
每轮迭代新加入一种面额的硬币,只对上一行dp数组进行更新,因此可以优化为一维数组:
class Solution {
public int change(int amount, int[] coins) {
if (coins.length * amount == 0) {
return amount == 0 ? 1 : 0;
}
int[] dp = new int[amount + 1];
dp[0] = 1;
for (int coin : coins) {
for (int j = coin; j <= amount; j++) {
dp[j] += dp[j - coin];
}
}
return dp[amount];
}
}

浙公网安备 33010602011771号