🚀 题目来源:力扣:322. 零钱兑换
题目
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11输出:3解释:11 = 5 + 5 + 1
示例 2:
输入:coins = [2], amount = 3输出:-1
示例 3:
输入:coins = [1], amount = 0输出:0
示例 4:
输入:coins = [1], amount = 1输出:1
示例 5:
输入:coins = [1], amount = 2输出:2
提示:
- 1 <= coins.length <= 12
- 1 <= coins[i] <= 231 - 1
- 0 <= amount <= 104
解题
暴力递归
function coinChange(coins = [], amount = 0) {// 递归function dp(n) {// 遇到 0,代表找到一个解,递归结束if (n === 0) return 0;// 如果 n < 0,代表无解if (n < 0) return -1;// 先设置一个比较大的数var res = Number.MAX_SAFE_INTEGER;// 循环所有的可能性for (const coin of coins) {// 递归求解const v = dp(n - coin);if (v === -1) continue;res = Math.min(res, 1 + v);}return res;}return dp(amount);}
添加备忘录
```javascript var dic = new Map();
function coinChange(coins = [], amount = 0) {
function dp(n) {if (dic.get(n)) return dic.get(n);if (n === 0) return 0;if (n < 0) return -1;var res = Number.MAX_SAFE_INTEGER;for (const coin of coins) {const v = dp(n - coin);if (v === -1) continue;res = Math.min(res, 1 + v);}dic.set(n, res);return res;}return dp(amount);
}
<a name="2YFEF"></a>## DP数组```javascriptfunction coinChange(coins = [], amount = 0) {var dp = new Array(amount + 1).fill(amount + 1);dp[0] = 0;for (let i = 0; i < dp.length; i++) {for (const coin of coins) {if (i - coin < 0) continue;dp[i] = Math.min(dp[i], 1 + dp[i - coin]);}}return (dp[amount] == amount + 1) ? -1 : dp[amount];}
