Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数

目录

70. 爬楼梯 (进阶)

322. 零钱兑换 

思路 

代码 

279.完全平方数 

思路 


70. 爬楼梯 (进阶)

70. 爬楼梯 - 力扣(LeetCode) 

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数_第1张图片 

// 版本一
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n; // 因为下面直接对dp[2]操作了,防止空指针
        vector dp(n + 1);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) { // 注意i是从3开始的
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
// 版本二
class Solution {
public:
    int climbStairs(int n) {
        if (n <= 1) return n;
        int dp[3];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            int sum = dp[1] + dp[2];
            dp[1] = dp[2];
            dp[2] = sum;
        }
        return dp[2];
    }
};
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

322. 零钱兑换 

322. 零钱兑换 - 力扣(LeetCode) 

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数_第2张图片 

思路 

1. 确定dp数组及其下标含义

        dp[j]:凑足总额为j所需钱币的最少个数为dp[j] 

2. 确定递推公式

dp[j] = min(dp[j - coins[i]] + 1, dp[j]);

3. dp数组初始化

vector dp(amount + 1, INT_MAX);
dp[0] = 0;

4. 确定遍历顺序

        如果求组合数就是外层for循环遍历物品,内层for遍历背包

        如果求排列数就是外层for遍历背包,内层for循环遍历物品

        遍历顺序为:coins(物品)放在外循环,target(背包)在内循环。且内循环正序。 

5. 举例推导dp数组

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数_第3张图片

代码 

class Solution {
public:
    int coinChange(vector& coins, int amount) {
        vector 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 * amount),其中 n 为 coins 的长度
  • 空间复杂度: O(amount)

279.完全平方数 

279. 完全平方数 - 力扣(LeetCode) 

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数_第4张图片 

思路 

1. 确定dp数组及其下标含义

        dp[j]:和为j的完全平方数的最少数量为dp[j] 

2. 确定递推公式

dp[j] = min(dp[j - i * i] + 1, dp[j]);

3. dp数组初始化

        dp[0] = 0, 非0下标的dp[j]一定要初始为最大值,这样dp[j]在递推的时候才不会被初始值覆盖。 

4. 确定遍历顺序

vector 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]);
    }
}

5. 举例推导dp数组 

Day39: 70. 爬楼梯 (进阶),322. 零钱兑换,279.完全平方数_第5张图片

class Solution {
public:
    int numSquares(int n) {
        vector 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];
    }
};
  • 时间复杂度: O(n * √n)
  • 空间复杂度: O(n)

笔记参考:代码随想录 

你可能感兴趣的:(算法,数据结构)