手撕LeetCode—70 爬楼梯

假设你正在爬楼梯。需要 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 步

这是一个很经典的问题了,记得高中的数学课上就讲过这个问题。这个问题如果按照正常的逻辑来思考,从第一层爬到顶有多少种方式,那就太复杂了,不符合我们算法求解的要求。

既然从第一层向上推导太复杂,那我们可以换一个思路:那就是从顶层往回退。假如我们要爬n层楼梯,还剩一层就到顶了,那么我们再向上走一步就能到顶,如果设爬上n-1层楼梯的方式有f(n-1)种,那么在这种情况下,我们爬上第n层也有f(n-1)种方式。

但是,还没有结束,因为最后一步可以爬1层也可以爬2层,那么我们爬上最后一层可以是从n-2层一次爬了2层到第n层。这种情况下,爬n层楼梯又有了f(n-2)中方式。

由于每次只能上1层或者2层楼梯,所以到达第n层的最后一步就只能是从n-1层爬1层,从n-2层爬两层。那么爬上n层楼梯的总方式就为f(n)=f(n-1)+f(n-2)。有没有很熟悉这个公式啊,对,这就是著名的斐波那契数列啊大笑

既然是熟悉的斐波那契数列,那就不多说了吧,直接上代码:

public int climbStairs(int n) {

    if (n == 0) {
        return 0;
    }

    if (n == 1) {
        return 1;
    }

    if (n == 2) {
        return 2;
    }

    return climbStairs(n - 1) + climbStairs(n - 2);

}

这是最简单的斐波那契数列的写法,使用了递归,但是这种写法的时间复杂度太大。

提交结果:

于是又经过思考,耗时太长的原因是使用了递归,能不能不用递归来实现呢?

public int climbStairs(int n) {

    if (n <= 1) {
        return 1;
    }
    
    int res = 0;
    int n1 = 1;
    int n2 = 1;
    for (int i = 2; i <= n; ++i) {
        res = n2 + n1;
        n1 = n2;
        n2 = res;
    }
    return res;
}

这次改进之后好多了得意




猜你喜欢

转载自blog.csdn.net/big_data1/article/details/80102646