Bootstrap

代码随想录算法训练营第三十二天 | 509. 斐波那契数 | 70. 爬楼梯 | 746. 使用最小花费爬楼梯

Day 32 总结

  • 自己实现中遇到哪些困难
  • 今日收获,记录一下自己的学习时间
    • 12:30 - 21:30

理论基础

代码随想录

  • 动态规划

    • 问题有很多的重叠子问题需要解决,状态涉及推导

  • DP 5部曲

    • DP数组含义

    • 状态转移公式

    • dp数组初始化

    • 数组遍历顺序

    • 举例推导

视频:从此再也不怕动态规划了,动态规划解题方法论大曝光 !| 理论基础 |力扣刷题总结| 动态规划入门_哔哩哔哩_bilibili

509. 斐波那契数

代码随想录

视频:手把手带你入门动态规划 | LeetCode:509.斐波那契数_哔哩哔哩_bilibili

题目链接:509. 斐波那契数 - 力扣(LeetCode)

题目描述:

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

实现思路:

为什么使用动态规划:计算 F(n)  的时候需要计算 F(n-1) F(n-2), 在计算他们的时候有包含重复的计算过程,所以需要对中间的计算结果进行保存。

dp数组:dp[i] 代表第 n 位斐波那契数的具体值

推导公式:dp[i] = dp[i-1] + dp[i-2]

初始化:i-2 >=0 , i-1 >=0, 初始化 dp[0] = 0 和 dp[1] = 1

遍历顺序:从 2 开始遍历

代码实现:

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+1; i++) {
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];
    }
}

70. 爬楼梯

代码随想录

视频:带你学透动态规划-爬楼梯(对应力扣70.爬楼梯)| 动态规划经典入门题目_哔哩哔哩_bilibili

题目链接:70. 爬楼梯 - 力扣(LeetCode)

题目描述:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢

实现思路:

为什么使用动态规划:爬第N层楼梯的方式,等于 爬N-1层的方式 + 爬N-2层的方式,因为可以选择从下面两层任意一层爬上来。但是计算下面楼层爬的方式的时候,会包含重复的计算,所以使用动态规划。

dp数组:dp[i] 代表爬第 i 层楼梯的方式数量

推导公式;dp[i] = dp[i-1] + dp[i-2]

初始化:i-1>=0 ,i-2>=0, i>=2需要初始化dp[0],dp[1]

遍历顺序:从2开始

代码实现:

class Solution {
    public int climbStairs(int n) {
        if (n <= 2) return n;
        int[] dp = new int[n+1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i=2; i<=n; i++)
            dp[i] = dp[i-1] + dp[i-2];
        return dp[n];
    }
}

746. 使用最小花费爬楼梯

代码随想录

视频讲解:动态规划开更了!| LeetCode:746. 使用最小花费爬楼梯_哔哩哔哩_bilibili

题目链接:746. 使用最小花费爬楼梯 - 力扣(LeetCode)

题目描述:

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

实现思路:

为什么使用动态规划:爬上台阶n可以从 n-1 爬上来,也可以从n-2爬上来,选择费用最低的方式即可。计算n-1的费用和n-2的费用时,包含重复计算,所以使用动态规划。

dp数组:dp[i] 代表第i层楼梯累计的费用

推导公式:dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])

初始化:需要初始化 dp[0] dp[1]

遍历顺序: 从2开始

代码实现:

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length+1];
        dp[0] = 0;
        dp[1] = 0;
        for (int i=2; i<=cost.length; i++) {
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[cost.length];
    }
}

;