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.

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

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

给定一些不同面值的硬币,和一个钱数。编写函数计算要得到目标金额有多少种不同的硬币组合方式。

322. Coin Change的变形,322题是求最少能用几个硬币组成给的钱数,而这题求的是组成给定钱数总共有多少种不同的方法。

解法:动态规划DP, 建立dp数组,保存能到达当前amount的步数。逐个金额遍历,看只用前i个金额能到达j的步数有多少,实现方法是累加起来dp[当前amount - 第i个金额],最后返回dp[amount]。

State: dp[i], 表示总额为i时的方案数

Function: dp[i] = Σdp[i - coins[j]],  表示总额为i时的方案数 = 总额为i-coins[j]的方案数的加和

Initialize: dp[0] = 1, 表示总额为0时方案数为1

Retrun: dp[n] or dp[-1]

Java:

public class Solution {
public int change(int amount, int[] coins) {
if (coins == null || coins.length == 0) {
return amount == 0? 1: 0;
}
int[] dp = new int[amount + 1];
dp[0] = 1;
for (int i = 0; i < coins.length; i ++) {
for (int j = 1; j <= amount; j ++) {
if (j >= coins[i]) {
dp[j] += dp[j - coins[i]];
}
}
}
return dp[amount];
}
}   

Python:

class Solution(object):
def change(self, amount, coins):
"""
:type amount: int
:type coins: List[int]
:rtype: int
"""
dp = [0] * (amount + 1)
dp[0] = 1
for c in coins:
for x in range(c, amount + 1):
dp[x] += dp[x - c]
return dp[amount] 

扩展思考:将上述代码中的循环顺序对调,即为求不同硬币的排列数(Permutation)

class Solution(object):
def change(self, amount, coins):
"""
:type amount: int
:type coins: List[int]
:rtype: int
"""
dp = [0] * (amount + 1)
dp[0] = 1
for x in range(amount + 1):
for c in coins:
if c > x: continue
dp[x] += dp[x - c]
return dp[amount]  

C++:

class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount + 1, 0);
dp[0] = 1;
for (int coin : coins) {
for (int i = coin; i <= amount; ++i) {
dp[i] += dp[i - coin];
}
}
return dp[amount];
}
};

类似题目:

[LeetCode] 322. Coin Change 硬币找零

[CareerCup] 9.8 Represent N Cents 组成N分钱

All LeetCode Questions List 题目汇总

[LeetCode] 518. Coin Change 2 硬币找零 2的更多相关文章

  1. [LeetCode] 518. Coin Change 2 硬币找零之二

    You are given coins of different denominations and a total amount of money. Write a function to comp ...

  2. [LeetCode] Coin Change 2 硬币找零之二

    You are given coins of different denominations and a total amount of money. Write a function to comp ...

  3. 【LeetCode】518. Coin Change 2 解题报告(Python)

    [LeetCode]518. Coin Change 2 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目 ...

  4. dp算法之硬币找零问题

    题目:硬币找零 题目介绍:现在有面值1.3.5元三种硬币无限个,问组成n元的硬币的最小数目? 分析:现在假设n=10,画出状态分布图: 硬币编号 硬币面值p 1 1 2 3 3 5 编号i/n总数j ...

  5. codevs 3961 硬币找零【完全背包DP/记忆化搜索】

    题目描述 Description 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从银行拿回最少的硬币数,并保证能用这些硬币发工资. 我们应该 ...

  6. NYOJ 995 硬币找零

    硬币找零 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 在现实生活中,我们经常遇到硬币找零的问题,例如,在发工资时,财务人员就需要计算最少的找零硬币数,以便他们能从 ...

  7. [LeetCode] Coin Change 硬币找零

    You are given coins of different denominations and a total amount of money amount. Write a function ...

  8. [LeetCode] 322. Coin Change 硬币找零

    You are given coins of different denominations and a total amount of money amount. Write a function ...

  9. [LeetCode] Lemonade Change 买柠檬找零

    At a lemonade stand, each lemonade costs $5.  Customers are standing in a queue to buy from you, and ...

随机推荐

  1. 有意义的单词分割——经典dfs题目

    680. 分割字符串 中文 English 给一个字符串,你可以选择在一个字符或两个相邻字符之后拆分字符串,使字符串由仅一个字符或两个字符组成,输出所有可能的结果 样例 样例1 输入: "1 ...

  2. Jmeter连接mysql,如何用delete、update、insert真正删除、更改、插入数据库里的数据;

    1.如下图,当插入数据的时候如图对应填写,查询数据的时候上面插入的那条数据就会显示,但是如果不执行下图的提交数据:到数据库里查的时候,插入的这条数据实际上并没有插入成功: . 结果:如果没有提交数据, ...

  3. 微信小程序中padding-right和margin-right无效

    在小程序中遇到样式padding-right和margin-right无效,调试发现设置了padding后,宽度已经大于页面的实际宽度,除了设置float:right之外,找不到办法让右侧paddin ...

  4. linux Crontab定时备份项目案例

    首先先写好备份的脚本(拷贝的命令) #bash/bin cd /finance/tomcat8-finance/wtpwebapps tar -czf /finance/webapp_backup/* ...

  5. 基于源代码为树莓派设备构建 TensorFlow

    本指南为运行 Raspbian 9.0 操作系统的 Raspberry Pi 嵌入式设备构建 TensorFlow.虽然这些说明可能也适用于其他系列的 Raspberry Pi 设备,但它仅针对此文中 ...

  6. MyBatis框架-ResultMap节点

    需求:查询结果要求显示用户名,用户密码,用户的角色 因为在用户表中只有用户角色码值,没有对应的名称,角色名称是在码表smbms_role表中,这时我们就需要联表查询了. 之前我们使用的是给查询结果字段 ...

  7. MySQL备份的三中方式

    一.备份的目的 做灾难恢复:对损坏的数据进行恢复和还原需求改变:因需求改变而需要把数据还原到改变以前测试:测试新功能是否可用 二.备份需要考虑的问题 可以容忍丢失多长时间的数据:恢复数据要在多长时间内 ...

  8. OLED液晶屏幕(0)自动获取12ic地址液晶屏幕

    . 烧录 串口可以看到输出的地址 #include <Wire.h> void setup(){ Wire.begin(); Serial.begin(9600); Serial.prin ...

  9. DOM内容梳理2

    JavaScript-DOM2(内容整理) 这两天新的知识有点多有点杂一时半会没有整理过来,以后不出意外会一直更行. js节点类型(NODETYPE) 查看节点类型 nodetype属性,返回的结果会 ...

  10. JavaScript高级程序编程(二)

    JavaScript 基本概念 1.区分大小写,变量名test与Test 是两个不同的变量,且函数命名不能使用关键字/保留字, 变量命名规范: 开头字符必须是字母,下划线,或者美元符号,ECMAScr ...