跳至主要內容

322. 零钱兑换


322. 零钱兑换

🟠   🔖  广度优先搜索 数组 动态规划  🔗 力扣open in new window LeetCodeopen in new window

题目

You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.

Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

You may assume that you have an infinite number of each kind of coin.

Example 1:

Input: coins = [1,2,5], amount = 11

Output: 3

Explanation: 11 = 5 + 5 + 1

Example 2:

Input: coins = [2], amount = 3

Output: -1

Example 3:

Input: coins = [1], amount = 0

Output: 0

Constraints:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 2^31 - 1
  • 0 <= amount <= 10^4

题目大意

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1

你可以认为每种硬币的数量是无限的。

解题思路

可以使用动态规化,定义一个数组dp,其中dp[i]表示凑齐金额i所需的最少硬币数。

  • 初始化数组 dp-666,便于后续取最小值。
  • 将 base case dp[0] 设置为 0,表示凑齐金额 0 不需要任何硬币。
  • 对于每个金额 i,遍历硬币的面额,计算凑齐金额 i 所需的最少硬币数。
  • 状态转移方程为:dp[i] = min(dp[i], dp[i - coin] + 1),其中 coin 为硬币的面额。
  • 最终,dp[amount] 即为凑齐总金额所需的最少硬币数。

复杂度分析

  • 时间复杂度O(n * amount),其中 n 是硬币的数量,amount 是目标金额。对于每个金额尝试使用每种硬币,因此在最坏情况下,可能对 amount 种金额进行 O(n) 次递归调用。
  • 空间复杂度O(amount)
    • 使用了一个长度为 amount + 1 的数组 dp
    • 递归调用的深度在最坏情况下可能达到 amount

代码

/**
 * @param {number[]} coins
 * @param {number} amount
 * @return {number}
 */
var coinChange = function (coins, amount) {
	let dp = new Array(amount + 1).fill(-666);

	const helper = (num) => {
		if (num == 0) return 0;
		if (num < 0) return -1;
		if (dp[num] !== -666) return dp[num];
		let res = Infinity;
		for (let coin of coins) {
			let sub = helper(num - coin);
			if (sub == -1) continue;
			res = Math.min(res, sub + 1);
		}
		dp[num] = res == Infinity ? -1 : res;
		return dp[num];
	};
	return helper(amount);
};

相关题目

题号标题题解标签难度力扣
983最低票价数组 动态规划🟠🀄️open in new window 🔗open in new window
2218从栈中取出 K 个硬币的最大面值和数组 动态规划 前缀和🔴🀄️open in new window 🔗open in new window
2224转化时间需要的最少操作数贪心 字符串🟢🀄️open in new window 🔗open in new window
2547拆分数组的最小代价数组 哈希表 动态规划 1+🔴🀄️open in new window 🔗open in new window
2902和带限制的子多重集合的数目数组 哈希表 动态规划 1+🔴🀄️open in new window 🔗open in new window
2915和为目标值的最长子序列的长度数组 动态规划🟠🀄️open in new window 🔗open in new window
2952需要添加的硬币的最小数量贪心 数组 排序🟠🀄️open in new window 🔗open in new window
2979最贵的无法购买的商品 🔒数学 动态规划 数论🟠🀄️open in new window 🔗open in new window