爬n阶楼梯,每次可以上一阶或者两阶,求有多少种上楼梯的方式!
这是刷帖子的时候发现的力扣的一道题,首先先来观察这道题的规律,第一阶有一种方式,第二阶有两种方式,第三阶有三种方式,第四阶有五种方式,第五阶有八种方式。到这里规律已经很明显了,那就是第n阶的方式为n-1阶+n-2阶的和!
规律出来了,我第一思路就是递归。代码如下
private static int palouti2(int n) {//时间O(2^n) 空间O(n)
if(n==1){
return 1;
}
if(n==2){
return 2;
}
return palouti2(n-1)+palouti2(n-2);
}
用这种方法挺简单的,但是在力扣上运行超时了,仔细一看发现这种方法的时间复杂度为O(2^n), 空间复杂度为O(n)。嗯!这不是一种好的方法!
进行下一种方法的思考,想起了学校学习的动态规划法,这里定义一个数组进行存放从1到n阶各有多少种方式,这样用时直接用就可以,不用进行重复计算,时间复杂度就变成了O(n)。代码如下:
public static int palouti(int n){//时间O(n) 空间O(n)
if(n==1){
return 1;
}
int[] db=new int[n+1];
db[1]=1;
db[2]=2;
for(int i=3;i<=n;i++){
db[i]=db[i-1]+db[i-2];
}
return db[n];
}
}
这次终于可以进行提交了!
随后去查看官方的解题方法,后面还用到了斐波那契数列和线代的公式和Binet'sFormula的解题方法,时间和空间复杂度大大降低,线代的知识全忘了,最后这种方法我都没听过~_~!!!
继续加深自己的知识栈吧!