Skip to content

反正基本思路就是遍历硬币,然后依次遍历数量。

零钱兑换:https://leetcode.cn/problems/coin-change/

零钱兑换 II:https://leetcode.cn/problems/coin-change-ii/

关于零钱2的变种类题目:

零钱2是组合,顺序不重要 这个是排列:(顺序比较重要)

相似的题是:LeetCode 377. 组合总和 Ⅳ (Combination Sum IV)https://leetcode.cn/problems/combination-sum-iv/description/ (挂羊头卖狗肉,名为组合实为排列)

假设你正在爬一个 n 阶的楼梯。你每次可以向上爬 1 阶、2 阶 或者 4 阶。请问,爬到楼顶(第 n 阶)一共有多少种不同的方法?(注意:不同的攀爬顺序被视为不同的方法。例如,1+2 和 2+1 是两种不同的方法。)

关于完全背包类问题的两种遍历方式。顺序重要是排序,外背包内物品。 顺序不重要的是组合,外物品内背包。

  • 如果是01背包,一般是外物品后背包。
js
function solveCounting(target, nums) {
    const dp = new Array(target + 1).fill(0);
    dp[0] = 1;

    // 决策点:这是排列还是组合?
    
    // CASE A: 爬楼梯 / 组合总和 IV (顺序重要 -> 排列)
    // 逻辑:背包在外,物品在内
    /*
    for (let i = 1; i <= target; i++) {       // 遍历背包
        for (let num of nums) {               // 遍历物品
            if (i >= num) dp[i] += dp[i - num];
        }
    }
    */

    // CASE B: 零钱兑换 II (顺序不重要 -> 组合)
    // 逻辑:物品在外,背包在内
    /*
    for (let num of nums) {                   // 遍历物品
        for (let i = num; i <= target; i++) { // 遍历背包
            dp[i] += dp[i - num];
        }
    }
    */

    return dp[target];
}

综上:

下次拿到这种题,按这个流程思考:

  1. 是背包问题吗?(能从一堆数里凑出一个总和) -> Yes.
  2. 物品能重复用吗?
    • 不能 -> 0/1 背包 -> 内层循环倒着写。
    • 能 -> 完全背包 -> 内层循环正着写。
  3. 求的是什么?
    • 求最值 (Min/Max) -> 循环顺序无所谓 (习惯先物品)。
    • 求方案数 (Count) -> 看顺序!
      • 顺序无关 (组合) -> 先物品 (零钱II)。
      • 顺序有关 (排列) -> 先背包 (组合IV, 爬楼梯)。
本站访客数 人次 本站总访问量