You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.
Example 1:
Input: amount = 5, coins = [1, 2, 5] Output: 4 Explanation: there are four ways to make up the amount: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1
Example 2:
Input: amount = 3, coins = [2] Output: 0 Explanation: the amount of 3 cannot be made up just with coins of 2.
Example 3:
Input: amount = 10, coins = [10] Output: 1
Note:
You can assume that
- 0 <= amount <= 5000
- 1 <= coin <= 5000
- the number of coins is less than 500
- the answer is guaranteed to fit into signed 32-bit integer
零钱兑换II。
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
思路依然是动态规划,同时这是一道完全背包问题。背包问题的定义是一个组合的不同排列在结果集里只出现过一次,比如 [1, 1, 2] 和 [1, 2, 1],只能算是一种情况。
dp[i] 的定义是当 amount = i 的时候,到底有几种硬币组合。以基本情况没有硬币开始组合数量。初始化 dp[0] = 1,其余等于 0。遍历所有硬币面值
- 对于每个硬币coin,我们将从金额 coin 遍历到 amount
- 对于每个 x,计算组合数:dp[x] += dp[x - coin]
- 返回 dp[amount]
时间O(n^2)
空间O(n)
Java实现
1 class Solution { 2 public int change(int amount, int[] coins) { 3 int[] dp = new int[amount + 1]; 4 dp[0] = 1; 5 for (int coin : coins) { 6 for (int x = coin; x < amount + 1; x++) { 7 dp[x] += dp[x - coin]; 8 } 9 } 10 return dp[amount]; 11 } 12 }
JavaScript实现
1 /** 2 * @param {number} amount 3 * @param {number[]} coins 4 * @return {number} 5 */ 6 var change = function(amount, coins) { 7 let dp = new Array(amount + 1).fill(0); 8 dp[0] = 1; 9 for (let coin of coins) { 10 for (let x = coin; x < amount + 1; x++) { 11 dp[x] += dp[x - coin]; 12 } 13 } 14 return dp[amount]; 15 };
相关题目