题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
解法一
递归无脑暴力求解,时间复杂度(O(2^n))
public int climbStairs(int n) {
return climb_Stairs(0,n);
}
public int climb_Stairs(int i,int n){
if(i > n) return 0;
if(i == n) return 1;
return climb_Stairs(i+1,n) + climb_Stairs(i+2,n);
}
解法二
解法一的优化版,增加了一个数组缓存中间的结果,当再次调用的时候再返回结果。时间复杂度O(n)
还有一些在思考这道题具体内存是如何存储中间数据的,如何返回的,这些思考以后补充(递归应该是用脑子和纸跑程序里最废脑细胞和纸的,还是太菜了。)
public int climbStairs(int n) {
int[] memo = new int[n + 1];
return climb_Stairs(0,n,memo);
}
public int climb_Stairs(int i,int n,int[] memo){
if(i > n) return 0;
if(i == n) return 1;
if(memo[i] > 0) {
//System.out.println("如果memo[ "+ i + " ]>0 "+Arrays.toString(memo));
return memo[i];
}
//System.out.println(i+"-- --"+Arrays.toString(memo));
memo[i] = climb_Stairs(i+1,n,memo) + climb_Stairs(i+2,n,memo);
//System.out.println(i+"--------------------"+Arrays.toString(memo));
return memo[i];
}
解法三
写递归的时候就能发现中间产生值是个斐波那契数,所以:
public int climbStairs(int n) {
if (n <= 2) return n;
int f1 = 1,f2 = 2,f3 = 3;
for(int i = 3; i < n + 1; i++) {
f3 = f1 + f2;
f1 = f2;
f2 = f3;
}
return f3;
}