← [ BACK_TO_NOTES ]

零钱兑换

完全背包最小值经典题:硬币可重复使用,求凑成目标金额的最少硬币数。

#algorithm #snippet #growing #leetcode #dp

[!info] related notes 算法面试题型 MOC 动态规划 背包 DP

零钱兑换

题目链接:https://leetcode.cn/problems/coin-change/

题意

给你若干硬币面值 coins,每种硬币都可以使用无限次。问凑成金额 amount 的最少硬币数;如果凑不出来,返回 -1。

硬币面值按题意为正整数,amount 为非负整数;本题求最少枚数,不是组合数量(见 零钱兑换 II)。

为什么是完全背包

  • 每个硬币可以重复使用
  • 目标是“凑出金额 amount”
  • 求的是最小值

状态

dp[j] 表示凑出金额 j 所需的最少硬币数。

转移

对于每个硬币 coin:

dp[j] = min(dp[j], dp[j - coin] + 1)

为什么正序

因为当前硬币可以重复使用,所以当前轮更新过的 dp[j - coin] 可以继续参与后面的转移。

边界

  • dp[0] = 0
  • 其他位置初始化成 INF

样例

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

  • 11 = 5 + 5 + 1
  • 最少需要 3 枚

JavaScript

var coinChange = function(coins, amount) {
    const dp = new Array(amount + 1).fill(Infinity);
    dp[0] = 0;

    for (const coin of coins) {
        for (let j = coin; j <= amount; j++) {
            dp[j] = Math.min(dp[j], dp[j - coin] + 1);
        }
    }

    return dp[amount] === Infinity ? -1 : dp[amount];
};

易错点

  • 初始化不能全填 0,否则最小值模型会错
  • 在“硬币外层、金额内层”的压缩写法中要正序;倒序会把每种硬币限制为最多使用一次
  • amount = 0 返回 0;无法凑出的状态保持 Infinity
创建于 2026/3/18 更新于 2026/10/7
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本