Skip to content

Latest commit

 

History

History
121 lines (93 loc) · 5.72 KB

0322.md

File metadata and controls

121 lines (93 loc) · 5.72 KB
title description keywords
322. 零钱兑换
LeetCode 322. 零钱兑换题解,Coin Change,包含解题思路、复杂度分析以及完整的 JavaScript 代码实现。
LeetCode
322. 零钱兑换
零钱兑换
Coin Change
解题思路
广度优先搜索
数组
动态规划

322. 零钱兑换

🟠 Medium  🔖  广度优先搜索 数组 动态规划  🔗 力扣 LeetCode

题目

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