5.10 零钱兑换
零钱兑换
问题描述
给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。
请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。
假设每一种面额的硬币有无限个。
1 | 输入:amount = 5, coins = [1, 2, 5] |
问题分析
- 典型的动态规划
- 典型的完全背包问题
策略选择
- 动态规划
- 采取两个方向上的动态规划。两个方向上的动态规划是非等价独立的。
- 数组矩阵线性数据结构
算法设计
阶段划分:规模增长的方向有两个。第一个规模增长的方向是硬币的种类。第二个规模增长的方向是金钱的总量。
状态变量dp[i][j]表示使用第i个硬币,达到j分钱所有的可能。
状态转移方程
- if k*coins[i]== amount dp[i][j]++;
- if kcoins[i]<amount dp[i][j]+=dp[i-1][j-kconis[i]] foreach k
边界条件
- 当amount=0应该只有一种策略,一个不选。当amount=n、i=coins.size()终止
补充:可以对状态空间进行压缩,提出了一种改进方案。直接以硬币的数目作为第二层遍历。
算法分析
时间复杂度O(mn)
空间复杂度O(mn)
算法实现
1 | class Solution { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Estom的博客!




