数据结构与算法之动态规划: Leetcode 70. 爬楼梯 (Typescript版)

  • Post author:
  • Post category:其他




爬楼梯

  • https://leetcode.cn/problems/climbing-stairs/



描述

  • 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
  • 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?



示例 1

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶



示例 2

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶



提示

  • 1 <= n <= 45



算法实现

1 )方案 1

function climbStairs(n: number): number {
    // n为1的情况
    if(n < 2) {
        return 1
    }
    let dp: number[] = [1,1]; // 初始化工具
    for(let i:number = 2; i <= n; ++ i) {
        dp[i] = dp[i-1] + dp[i-2]
    }
    return dp[n]
}
  • 思路

    • 爬到第n阶可以在n-1阶爬1个台阶,或在n-2阶爬两个台阶
    • F(n) = F(n-1) + F(n-2)

      • F(n) 代表n个台阶一共有多少种方法爬上去
      • 爬到第n阶方法数量 = 爬到n-1阶方法数量 + 爬到n-2阶方法数量
    • 一个问题可以分解为两个相互重叠的子问题,用动态规划解题
  • 步骤

    • 定义子问题:F(n) = F(n-1) + F(n-2)
    • 反复执行子问题:从2 ~ n, 执行上述公式
    • 这里的2,必须保证n-2是正的,如果只有1个台阶只有一个方法,而且1-2=-1,台阶数量不能为负数
  • 注意

    • dp 数组用来记录,第n阶需要多少种方法,下标为0的位置(0阶,当然n不能为0)设置成1
    • 下标为1的位置,1阶是1,为什么把下标为0的位置设置1,因为它能帮助方便求得2阶,真实情况下n不会等于0,此处需要的是工具值

2 )方案 2

function climbStairs(n: number): number {
    // n为1的情况
    if(n < 2) {
        return 1;
    }
    
    // 用两个变量来代表前两步
    let dp0 = 1;
    let dp1 = 1;

    for(let i: number = 2; i <= n; ++ i) {
        // 不断地把dp0, dp1分别代表数组的倒数两个数字
        let tmp = dp0;
        dp0 = dp1;
        dp1 += tmp; // 用常量取代数组,空间复杂度下降
    }
    return dp1;
}
  • 思路同上,优化了空间复杂度,官方给的滚动数组初始化的一些变量不太好理解,后面的矩阵快速幂方法比较复杂了,通项公式法就是用的数学推导



版权声明:本文为Tyro_java原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。