代码随想录算法训练营第四十五天|70. 爬楼梯 (进阶)、322. 零钱兑换 、279.完全平方数

70. 爬楼梯 (进阶)

文档讲解 : 代码随想录 - 70. 爬楼梯 (进阶)
状态:再次回顾。

动态规划五部曲:

  1. 确定dp数组(dp table)以及下标的含义
    dp[i]的定义为:爬到有i个台阶的楼顶,有dp[i]种方法。

  2. 确定递推公式
    dp[i] += dp[i - j];

  3. dp数组如何初始化
    dp[0] = 1 ;

  4. 确定遍历顺序
    排列,先遍历背包,再遍历物品。(不可以换顺序!)

  5. 举例推导dp数组:
    组合总和一样。

本题代码:
代码中m表示最多可以爬m个台阶

class Solution {
public:
    int climbStairs(int n) {
        vector<int> dp(n + 1, 0);
        dp[0] = 1;
        for (int i = 1; i <= n; i++) { // 遍历背包
            for (int j = 1; j <= m; j++) { // 遍历物品
                if (i - j >= 0) dp[i] += dp[i - j];
            }
        }
        return dp[n];
    }
};
  • 时间复杂度: O ( n m ) O(nm) O(nm)
  • 空间复杂度: O ( n ) O(n) O(n)

322. 零钱兑换

文档讲解 : 代码随想录 - 322. 零钱兑换
状态:再次回顾。

动态规划五部曲:

  1. 确定dp数组(dp table)以及下标的含义
    dp[i]的定义为:凑足总额为j所需钱币的最少个数为dp[j]

  2. 确定递推公式
    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);

  3. dp数组如何初始化
    dp[0] = 0 ;

  4. 确定遍历顺序
    先遍历背包,再遍历物品。(顺序可以颠倒!)

  5. 举例推导dp数组:
    以输入:coins = [1, 2, 5], amount = 5为例:
    dp数组

本题代码:

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i < coins.size(); i++) { // 遍历物品
            for (int j = coins[i]; j <= amount; j++) { // 遍历背包
                if (dp[j - coins[i]] != INT_MAX) { // 如果dp[j - coins[i]]是初始值则跳过
                    dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
                }
            }
        }
        if (dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};
  • 时间复杂度: O ( n ∗ a m o u n t ) O(n * amount) O(namount),其中 ncoins 的长度
  • 空间复杂度: O ( a m o u n t ) O(amount) O(amount)

279.完全平方数

文档讲解 : 代码随想录 - 279.完全平方数
状态:再次回顾。

动态规划五部曲:

  1. 确定dp数组(dp table)以及下标的含义
    dp[i]的定义为:和为j的完全平方数的最少数量为dp[j]

  2. 确定递推公式
    dp[j] = min(dp[j - i * i] + 1, dp[j]);

  3. dp数组如何初始化
    dp[0] = 0 ;

  4. 确定遍历顺序
    先遍历背包,再遍历物品。(顺序可以颠倒!)

  5. 举例推导dp数组:
    以输入n5例,dp状态图如下:
    dp数组

本题代码;

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 1; i * i <= n; i++) { // 遍历物品
            for (int j = i * i; j <= n; j++) { // 遍历背包
                dp[j] = min(dp[j - i * i] + 1, dp[j]);
            }
        }
        return dp[n];
    }
};
  • 时间复杂度: O ( n ∗ √ n ) O(n * √n) O(nn)
  • 空间复杂度: O ( n ) O(n) O(n)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值