这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战
前言
今天来一道有意思的算法练习题,本题的解法比较多,本文大致提三种解法和大家交流,下面我们先来看题目
题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
-
1 阶 + 1 阶
-
2 阶
示例 2:
输入: 3
输出: 3 解释: 有三种方法可以爬到楼顶。
-
1 阶 + 1 阶 + 1 阶
-
1 阶 + 2 阶
-
2 阶 + 1 阶
解题思路
- 看到本题的第一思路就是懵逼,如果台阶的个数少我还能把一个个情况列举出来数数,可如果情况多了该怎么办呢
- 通过把1-7个台阶的情况罗列出来,我发现除了1个台阶和两个台阶,也就是从三个台阶开始,以后的台阶个数能爬到楼顶的方法数都等于前一个台阶爬道楼顶个方法数加上前两个台阶数爬到楼顶的方法个数,也就是f(x)=f(x-1)+f(x-2),那么结果就很明显了,我们直接用递归就可解决问题,下面上代码
var climbStairs = function(n) {
if(n===1){
return 1
}
if(n===2){
return 2
}
return climbStairs(n-1)+climbStairs(n-2)
};
- emmm....,就是这么简单,于是我就去提交去了,可是结果却打了我的脸,超时了。。。。
- 说明这样是不行的,那就换种方法,前面说的方法是我们通过列举了前面几项的结果找出了f(x)=f(x-1)+f(x-2),这个公式必然是正确的,这里我们可以换种理解方式,也就是说,x-1阶台阶到x阶台阶的情况只有两种,要么是一次走一阶上来,要么是一次走两阶上来,这和我们前面找到的规律是相符的,只是对这个公式有了 更深的认识,这里我们可以当做动态规划,f(x)=f(x-1)+f(x-2)这就是我们的转移方程,接着我们只要考虑边界问题就行了,这里可以理解为我们是通过0走到0阶的,这里只有一种可能,也就是走了1步,当我们从 0阶到1阶也只有一种可能,当把这两个边界值都知道后我们就可以写代码了,如下
var climbStairs = function(n) {
let b=0,q=0,r=1;
for(let i=1;i<=n;i++){
b=q;
q=r;
r=b+q;
}
return r
};
总结
这题最终的代码看起来非常简便,但里面的思考却有很多,比如刚开始使用的递归方法,它超时了,其实我们可以优化一下它,比如记录下每阶所有的到达楼顶的方法,就不用每次做重复的运算了,又或者,我们可以有更极端的方法,我们可以把所有的情况看都计算出来,之所以可以这样是因为题目中说了n是个正整数,那么n所能满足的最大值也就是64,再大就溢出了,所以我们也可以把这n从1到64的情况都列出来,通过switch和case直接得到结果,这样的效率会更高,哈哈哈(但这是钻漏洞的方法,和算法就没什么关系了)