算法修炼Day45|70. 爬楼梯 (进阶) ● 322. 零钱兑换 ● 279.完全平方数

108 阅读2分钟

LeetCode:70. 爬楼梯 - 力扣(LeetCode)

1.思路

思路一:找规律。当前台阶走法是前两个台阶走法之和。台阶数小于2时,直接返回对应数值,台阶数大于等于3时,采用滚动的方式获取前两个台阶方式之和,返回结果即可。

思路二:动态规划。在上述找规律的基础上建立起来的推导逻辑。初始化时需要简单注意一下边界。

2.代码实现
// 方法一洗洗脑
class Solution {
    public int climbStairs(int n) {
        int a = 1, b = 2, c = 0;
        if (n <= 2) {
            return n;
        }
        for (int i = 3; i <= n; i++) {
            c = a + b;
            a = b;
            b = c;
        }
        return c;
    }
}
class Solution {
    public int climbStairs(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        // dp[2] = 2;
        for (int i = 2; i < n + 1; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}
3.复杂度分析

时间复杂度:O(n).

空间复杂度:O(n).

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

1.思路

理解题意,从coins[]数组中获取物品填进容量为amount的背包中是否有值存在?存在的话返回最小值。

2.代码实现
class Solution {
    public int coinChange(int[] coins, int amount) {
        // 动规
        int[] dp = new int[amount + 1]; // 初始化容量为最大值
        for (int i = 0; i < dp.length; i++) {
            dp[i] = Integer.MAX_VALUE; // 求最小值,故应该把对应默认值都初始化为int的最大值
        }
        dp[0] = 0;
        // 遍历推导
        for (int i = 0; i < coins.length; i++) {
            for (int j = coins[i]; j <= amount; j++) {
                if (dp[j - coins[i]] != Integer.MAX_VALUE) { // 当前一个值为int的最大值时是无效的
                    dp[j] = Math.min(dp[j], dp[j - coins[i]] + 1);
                }
            }
        }
        return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
    }
}
3.复杂度分析

时间复杂度:O(n^2).

空间复杂度:O(n).

LeetCode:

1.思路

理解题意:将完全平方数塞入容量为n的背包,最少需要几个完全平方数。完全平方数为物品,n为背包。注:一定可以装满,全用1装,也是最大值。

2.代码实现
class Solution {
    public int numSquares(int n) {
        // 动规
        int[] dp = new int[n + 1];
        // 求最小值,先声明为最大值
        for (int i = 0; i <= n; i++) {
            dp[i] = Integer.MAX_VALUE;
        }
        dp[0] = 0;
        // 遍历 + 推导
        for (int i = 1; i * i <= n; i++) { // 遍历完全平方数 i^2
            for (int j = i * i; j <= n; j++) { // 遍历背包
                // if (dp[j - i ^ 2] != Integer.MAX_VALUE) {
                    dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
                // }
            }
        }
        return dp[n];
    }
}
3.复杂度分析

时间复杂度:O(n ^ 2).

空间复杂度:O(n).