(递归)LeetCode70爬楼梯

                                             爬楼梯的几种解法

第三天的打卡,今天没有上网课,下次上网课大概是明天吧。 

题目描述

 

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

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

注意:给定 n 是一个正整数。

示例 1:

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

示例 2:

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

题目原链接https://leetcode-cn.com/problems/climbing-stairs/

解题思路描述

最简单的方法就是只考虑最后一个台阶的走法,当没有台阶,返回0,还有一层台阶,返回1,即剩一个台阶时只有一种方法,离终点有两层台阶时,有两种可能,1+1或2(一次迈两个台阶或者一次迈一个台阶,走两步),所以返回2。这样就设置好了递归的出口,其他需要我们做的就是进行递归了,把一次迈两个台阶和一次迈一个台阶的方法数加起来。思路整理如下:

  • 设置递归出口,没有台阶,剩一个台阶和剩两个台阶的方法数写出来。
  • 调用自身 f(n-1)+ f(n-2)走一步的方法数和走两步的方法数之和。

代码如下

class Solution {
public:
    int climbStairs(int n) {
        if(n == 0) return 0;//当只剩最后一层楼梯时没有办法选择,因此是0种方案
        if(n == 1) return 1;
        if(n == 2) return 2;
        return climbStairs(n-1) + climbStairs(n-2);

    }
};

但递归中进行循环次数过多,导致计算结果超过了时间限制。

这种方法是代码最简洁的,但是却超出了时间限制,并且时间复杂度过于高,可以达到O(2∧n)。

下图为官方给出的n=5时的递归树。

Climbing_Stairs

针对递归法的改良

          针对暴力破解即递归法,可以进行的改良是写一个大小为n+1的数组,数组内存放运算所得的值即【0,1,2,3,。。。。。】(数组的索引是台阶数,而值则是程序运算所得的解法),这样在递归的时候,如果可以从数组中找到值的步骤就直接返回值,再不断把运算过程中产生的结果(数组中暂时没有的值)存放到数组中,以备下次计算,可以减少迭代的次数,同时增加运算速度。

解题的第二种方法

        我认为是把递归转化为循环,这样可以把时间复杂度由原来的O(2∧n)减小到O(n)。因为只需要一个for语句。思路和递归的思路类似。递归是只考虑最后一步,即只想结果不想过程。循环的话就从第一个台阶开始思考。只有一个台阶的话,是一种方法,两个台阶,是两种方法。推理一下,三个台阶,第一次迈一个台阶,方法数就是走两个台阶的方法数,第一次迈两个台阶,就是走一个台阶的方法数,以此类推。简单描述如下:

  • 用函数表示爬楼梯,则参数n表示楼梯数,f(n)表示一共的方法数。
  • 经过前面的思考,可以知道f(1)= 1 ,f(2)= 2,f(3)= f(1)+ f(2)。
  • 推理可得f(4)= f(3)+ f(2),f(5)= f(4)+ f(3),f(n)= f(n-1)+ f(n-2)
  • 带入循环中,可以从 f(3) 求解到f(n)。

代码如下

class Solution {
public:
    int climbStairs(int n) {
        int* res = new int[n+1];
        if( n == 1 ) return 1;
        res[1] = 1 ;
        res[2] = 2 ;
        if( n > 2 ){
            for(int i = 3 ; i <= n ; i ++){
                res[i] = res[i-1] + res[i-2];
            }
        }
        return res[n];

    }
};

 

提交结果如下

 

执行用时是很快的,在毫秒级以内。

 

今日打卡结束,生命不止,学习不休。

女人皆祸水,美妙仅两回,或是坠爱河,或是临终前-----《卡门》

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值