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

参考

代码随想录

题目一:LeetCode 70. 爬楼梯

这个题之前已经做过,因为题目中给出一次可以1个或者2个台阶,所以这个题比较简单,但是如果改成一个可以爬m个台阶,就需要用完全背包的解法来做 了。

  1. 确定dp数组及其下标的含义
    dp[j]:爬到第j个台阶,有dp[j]中方法
  2. 确定递推公式
    dp[j] += dp[j - i]
  3. dp数组初始化
    dp[0] = 1,其他初始化为0
  4. 确定遍历顺序
    爬楼梯的过程是个排列问题,爬一个台阶+爬两个台阶与爬两个台阶+爬一个台阶是不一样的,因此外层循环遍历背包,内层循环遍历物品。
    5.举例推导dp数组
n = 3
dp[0] = 1
dp[1] = dp[0] = 1
dp[2] = dp[0] + dp[1] = 2
dp[3] = dp[2] = dp[1] = 3

完整的代码实现如下:

class Solution {
public:
    int climbStairs(int n) {
        vector<int> dp(n+1,0);
        dp[0] = 1;
        int m = 2; //对于本题,m = 2
        for(int j = 0; j <= n; j++){  //遍历背包
            for(int i = 1; i <= m; i++){	//遍历物品
                if(j >= i)
                    dp[j] += dp[j-i];
            }
        }
        return dp[n];
    }
};

题目二:LeetCode 322. 零钱兑换

  1. 确定dp数组及其下标的含义
    dp[j]:凑足总额为j所需钱币的最少个数为dp[j]
  2. 确定递推公式
dp[j] = min(dp[j],dp[j-coins[i]] + 1)
  1. dp数组初始化
    dp[0] = 0,其余初始化为INT_MAX
  2. 确定遍历顺序
    这个题不用关心是排列还是组合,只需要关注钱币的最少个数即可,因此两种遍历顺序都可以。
  3. 推导dp数组
coins = [1,2,5],amount = 5
dp = [0,1,1,2,2,1]

完整的代码实现如下:

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] = min(dp[j],dp[j-coins[i]]+1);
            }
        }
        return dp[amount] == INT_MAX ? -1 : dp[amount];
    }
};

题目三:LeetCode 279.完全平方数

  1. 确定dp数组及其下标的含义
    dp[j]:和为j的完全平方数的最少数量为dp[j]
  2. 确定递推公式
dp[j] = min(dp[j - i * i] + 1, dp[j])
  1. dp数组初始化
    dp[0] = 0,其余初始化为INT_MAX
  2. 确定遍历顺序
    本题求的是最少个数,因此两种遍历顺序都是可以的。
  3. 举例推导dp数组
n = 5
dp = [0,1,2,3,1,2]

完整的代码实现如下:

class Solution {
public:
    int numSquares(int n) {
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i <= n; i++) { // 遍历背包
            for (int j = 1; j * j <= i; j++) { // 遍历物品
                dp[i] = min(dp[i - j * j] + 1, dp[i]);
            }
        }
        return dp[n];
    }
};

你可能感兴趣的:(代码随想录训练营,leetcode,动态规划,算法)