LeetCode Day38|● 理论基础(五部曲:1.数组含义2.公式3.初始化4.顺序5.打印)● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

本文详细介绍了动态规划的基本理论、常见题型(如斐波那契、爬楼梯等),纠正了常见的误区,并通过实例展示了dp数组的定义、递推公式、初始化、遍历顺序和打印dp数组的过程,总结了动态规划的五步法。
摘要由CSDN通过智能技术生成

day 38-1 理论基础

动态规划的常见题型

  • 基础类题型:斐波拉契、爬楼梯
  • 背包问题:大厂容易考
  • 打家劫舍:
  • 股票问题:
  • 子序列问题:最长递增子序列、最长连续递增子序列、编辑距离问题

动态规划的误区

  • 要掌握本质性的解题步骤

dp数组的定义以及下标的含义

  • 要考虑清楚

递推公式

  • 递推公式很重要,但是只说一部分

dp数组初始化

  • 开头初始化为0
  • 开头初始化为1
  • 全部初始化为1
  • eg.不同路径

dp数组遍历顺序

eg.背包问题:遍历背部和物品的顺序可以交换? 否

打印dp数组

  • 用于调试错误

动态规划五部曲总结

  1. 明确dp数组以及下标的含义
  2. 递推公式
  3. dp数组的初始化
  4. 遍历顺序
  5. 打印dp数组

day 38-2 509. 斐波那契数

简单题目是用来加深对解题方法论的理解的。

  • eg.1 1 2 3 5 8 的规划五部曲:
    • 1.确定dp[i]的含义:dp[i]:第i个斐波拉契数的值为dp[i]
    • 2.递归公式(题目已给出):dp[i] = dp[i - 1] + dp[i - 2]
    • 3.dp数组如何初始化(题目也已给出):dp[0] = 1 dp[1] = 1
    • 4.遍历顺序(符合默认的思维模式):从前往后
    • 5.打印dp数组
  • 时间消耗:00:08:34
class Solution {
    // 非压缩版
    // public int fib(int n) {
    //     if(n<=1){
    //         return n;
    //     }
    //     int[] dp = new int[n+1];
    //     dp[0] = 0;
    //     dp[1] = 1;
    //     for(int i = 2; i<=n; i++){
    //         dp[i] = dp[i - 1] + dp[i -2];
    //     }
    //     return dp[n];
    // }

    // 压缩版1
    // public int fib(int n){
    //     if(n<=1){
    //         return n;
    //     }
    //     int a = 0, b = 1,sum = 0;
    //     for(int i = 2; i<=n; i++){// i只会起到一个计数作用
    //         sum = a + b;
    //         a = b;
    //         b = sum;
    //     }
    //     return sum;
    // }

    // 压缩版2
    // public int fib(int n){
    //     if(n<=1){
    //         return n;
    //     }
    //     int[] dp = new int[2];
    //     dp[0] = 0; 
    //     dp[1] = 1;
    //     int sum = 0; 
    //     for(int i = 2; i<=n; i++){// i只会起到一个计数作用
    //         sum = dp[0] + dp[1];
    //         dp[0] = dp[1];
    //         dp[1] = sum;
    //     }
    //     return sum;
    // }
    //递归法
    public int fib(int n){
        // 递归三部曲:
        // 1.找到递归的终止条件
        // 2.找返回值
        // 3.本级递归应该做什么
        if(n<=1){
            return n;
        }
        return fib(n-1) + fib(n-2);
    }
}

day 38-3 70. 爬楼梯

递推过程
规划五部曲:

  1. 确定dp[i]的含义:达到i阶有dp[i]种方法
  2. 递归公式:dp[i] = dp[i - 1] + dp[i - 2]
  3. dp数组如何初始化:dp[0] = 1/dp[0]=0(无意义) dp[1] = 1 dp[2] = 2
  4. 遍历顺序:从前往后 (很多动态规划的题目是从后往前遍历的)
  5. 打印dp数组
    n=5的例子情况
  • 耗时: 00:07:11
    拓展:一步不适可以走1-2个台阶而是可以走m个台阶,问要排n阶的楼梯有多少种方法—>完全背包的思路解决
class Solution {
    // 非压缩
    // public int climbStairs(int n) {
    //     if(n == 1){
    //         return 1;
    //     }
    //     if(n == 2){
    //         return 2;
    //     }
    //     int[] dp = new int[n + 1];
    //     dp[1] = 1;
    //     dp[2] = 2;
    //     for(int i = 3; i <= n; i++){
    //         dp[i] = dp[i-1] + dp[i-2];
    //     }
    //     return dp[n];
    // }
    // 压缩
    // public int climbStairs(int n){
    //     if(n <= 2){
    //         return n;
    //     }
    //     int[] dp = new int[3];
    //     dp[1] = 1;
    //     dp[2] = 2;
    //     int sum = 0;
    //     for(int i = 3; i <= n; i++){
    //         sum = dp[1] + dp[2];
    //         dp[1] = dp[2];
    //         dp[2] = sum; 
    //     }
    //     return sum;
    // }
    // 递归
    public int climbStairs(int n){
        if(n<=2){
            return n;
        }
        return climbStairs(n-1) +climbStairs(n-2);
    }
} 

day38-4 746. 使用最小花费爬楼梯

规划五部曲:

  1. 确定dp[i]的含义:达到第i台阶位置所花费的最小体力dp[i]
  2. 递归公式:dp[i] = min(dp[i - 1]+cost[i-1],dp[i-2] + cost[i-2])
  • dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1]
  • dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]
  1. dp数组如何初始化:dp[0] = 0, dp[1] = 0
  2. 遍历顺序:从前往后 (很多动态规划的题目是从后往前遍历的)
  3. 打印dp数组
  • 耗时:00:06:10
class Solution {
    // 第一步不支付费用
    public int minCostClimbingStairs(int[] cost) {
        int len = cost.length;
        // dp[i]的定义:达到第i台阶位置所花费的最小体力dp[i]
        int[] dp = new int[len + 1];

        // dp数组初始化
        dp[0] = 0;
        dp[1] = 0;
        
        // 递推公式
        for(int i = 2; i <= len; i++){
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[len];
    }
}

总结统计

  • 总耗时:01:29:19
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值