Leetcode第70题: 爬楼梯

一、题目来源:leetcode第70题

二、题目描述

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

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

示例 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

三、解题

3.1 解法一

  1. 思路

思考到爬楼梯的规律其实就是符合斐波那契数列(Fibonacci Sequence) 规律的,问题就迎刃而解了。为什么说它是斐波那契数列呢?我们可以这样来思考:当我们从第 n-1 阶楼梯爬到第 n 阶楼梯时,需要1步;当我们从第 n-2 阶楼梯爬到第 n 阶楼梯时,需要2步。也就是说,到达第 n 阶楼梯的方法数等于到达第 n-1 阶楼梯的方法数加上到达第 n-2 阶楼梯的方法数,即 f(n)=f(n−1)+f(n−2),正好符合斐波那契通项。

  1. 解法
var climbStairs = function ( n ) {
    if (n === 1 || n === 2 ) return n;
    return  climbStairs (n- 1 ) + climbStairs (n- 2 );
}; 
  1. 时间复杂度

由于递归调用了两次climbStairs函数,每次减少的阶数是n-1n-2,所以递归树的高度是n。因此,时间复杂度可以表示为O(2^n)

  1. 空间复杂度

在递归过程中,每次调用climbStairs函数都会产生一个新的函数调用栈帧,该栈帧保存了函数的局部变量和返回地址。由于递归调用的次数取决于输入的n值,所以递归树的深度是n。因此,空间复杂度可以表示为O(n)

3.2 解法二

  1. 思路

使用数组来保存中间结果,降低时间复杂度。

  1. 解法
var climbStairs = function ( n ) {
    let result = [ 1 , 2 ];
    for ( let i = 2 ; i < n; i++) {
        result. push (result[i- 1 ] + result[i- 2 ]);
    }
    return result[n- 1 ];
}; 
  1. 时间复杂度

for循环中,需要迭代n-2次,每次计算result[i]的值。因此,时间复杂度为O(n)

  1. 空间复杂度

    在算法执行过程中,只使用了一个数组result来保存中间结果,其长度为n。因此,空间复杂度为O(n)

3.3 解法三

  1. 思路

    用三个变量代替数组来储存结果,降低空间复杂度。

  2. 解法
var climbStairs = function ( n ) {
    let p = 0, q = 0, r = 1;
    for ( let i = 1 ; i <= n; i++) {
        p = q;
        q = r;
        r = p + q;
    }
    return r;
}; 
  1. 时间复杂度

    for循环中,迭代了n次,每次计算需要常数时间。因此,时间复杂度为O(n)

  2. 空间复杂度

    在算法执行过程中,只使用了三个变量pqr来保存中间结果。这三个变量的空间占用是常数级别的。因此,空间复杂度为O(1)

四、知识点

动态规划(Dynamic Programming) 是一种解决多阶段决策问题的优化方法。它通过将原问题分解为若干个子问题,并保存子问题的解,以避免重复计算,从而在时间复杂度上实现优化。

下面是解决动态规划问题的一般步骤:

  1. 确定问题的最优解结构:分析问题的特点,确定问题可以划分为多个阶段,并且当前阶段的最优解可以由之前阶段的最优解得到。
  2. 定义状态:确定动态规划的状态,即表示问题的子问题的解的状态。状态的选择要满足无后效性和最优子结构性质。
  3. 建立状态转移方程:根据问题的最优解结构和子问题之间的关系,建立状态转移方程。该方程描述了当前阶段的最优解与之前阶段的最优解之间的关系。
  4. 初始化边界条件:确定初始阶段的最优解或边界条件,以便开始递推计算。
  5. 使用迭代或递归方式求解:根据状态转移方程,通过迭代或递归方式计算每个阶段的最优解,并保存在一个表格或数组中。
  6. 构造最优解:根据保存的中间结果,从最终阶段开始,逆向推导出问题的最优解。
  7. 分析时间复杂度和空间复杂度:评估动态规划算法的时间复杂度和空间复杂度,并进行优化。

动态规划常常用于解决具有重叠子问题和最优子结构性质的问题,例如背包问题、最长公共子序列问题、最短路径问题等。

  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值