LeetCode518-零钱兑换II

题目链接

英文链接:https://leetcode.com/problems/coin-change-2/

中文链接:https://leetcode-cn.com/problems/coin-change-2/

题目详述

给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

示例 1:

1
2
3
4
5
6
7
输入: amount = 5, coins = [1, 2, 5]
输出: 4
解释: 有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

示例 2:

1
2
3
输入: amount = 3, coins = [2]
输出: 0
解释: 只用面额2的硬币不能凑成总金额3。

示例 3:

1
2
输入: amount = 10, coins = [10] 
输出: 1

注意:

你可以假设:

  • 0 <= amount (总金额) <= 5000
  • 1 <= coin (硬币面额) <= 5000
  • 硬币种类不超过 500 种
  • 结果符合 32 位符号整数

题目详解

  • 完全背包,类似于 LeetCode322-零钱兑换,只不过本题求的是组合总数。
  • 实际上,本题与 LeetCode377-组合总和IV 更为相似,都是求组合数。只是 LeetCode377-组合总和IV 组合具有顺序信息,需要采用先枚举容量再枚举物品的方式,而本题采用先枚举物品再枚举容量。
  • f(i) 表示硬币总面值为 i 时的方案数,则有 f(i) = f(i) + f(i - coin), i >= coin
  • 初始时 f(0) = 1,最终答案为 f(amount)
1
2
3
4
5
6
7
8
9
10
11
12
13
public class LeetCode_00518 {

public int change(int amount, int[] coins) {
int[] f = new int[amount + 1];
f[0] = 1;
for (int coin : coins) {
for (int i = coin; i <= amount; ++i) {
f[i] += f[i - coin];
}
}
return f[amount];
}
}