leetcode 70. 爬楼梯问题(多种方法总结)
爬楼梯问题有多种出现形式,有不固定最多可跨阶数(即最多可跨阶数为M,M作为方法参数)的,有固定每次最多可跨2阶的。接下来,我就对以上两种出线形势分别进行分析。
(一)固定每次最多跨越2阶,使用非递归方式实现:
1、问题描述:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
2、首先我们把 n<=5 的不同情况列出来:
1 | 2 | 3 | 4 | 5 |
1 | 2 | 3 | 5 | 8 |
综上我们可以看出,爬楼梯的方案数f(n) = f(n) + f(n-1)
3、我们用java代码实现以上思路:
class Solution {
public int climbStairs(int n) {
if(n==1||n==2){
return n;
}
int f1 = 1;
int f2 = 2;
int temp;
for(int i=3; i<=n; i++){
temp = f2;
f2 += f1;
f1 = temp;
}
return f2;
}
}
4、运行结果:
(二)使用递归方式实现
1、问题描述:
假设一个楼梯有 N 阶台阶,人每次最多可以跨 M 阶,求总共的爬楼梯方案数。
2、算法实现(java语言):
private static int calculateCount(int ladder, int maxJump) {
int jump = 0;
if (ladder == 0) {
return 1;
}
if (ladder >= maxJump) {
// 剩下的楼梯大于最大可跳跃数
for (int i = 1; i <= maxJump; i++) {
jump += calculateCount(ladder - i, maxJump);
}
} else {
// 剩下的楼梯不足最大可跳跃数
jump = calculateCount(ladder, ladder);
}
return jump;
}
(三)递归和非递归实现性能比较:
package test;
/**
*
* @author FHY
* 爬楼梯问题
*
*/
public class DynamicTest {
public static void main(String[] args) {
//对递归和非递归实现两种方法进行性能比较:
long start = System.currentTimeMillis();
getNums(30);
long end1 = System.currentTimeMillis();
System.out.println("非递归实现:"+(end1-start));
calculateCount(30,2);
long end2 = System.currentTimeMillis();
System.out.println("递归实现:"+(end2-end1));
}
private static int calculateCount(int ladder, int maxJump) {
int jump = 0;
if (ladder == 0) {
return 1;
}
if (ladder >= maxJump) {
// 剩下的楼梯大于最大可跳跃数
for (int i = 1; i <= maxJump; i++) {
jump += calculateCount(ladder - i, maxJump);
}
} else {
// 剩下的楼梯不足最大可跳跃数
jump = calculateCount(ladder, ladder);
}
return jump;
}
public static int getNums(int n){
if(n==1||n==2){
return n;
}
int f1 = 1;
int f2 = 2;
int temp;
for(int i=3; i<=n; i++){
temp = f2;
f2 += f1;
f1 = temp;
}
long end = System.currentTimeMillis();
return f2;
}
}
输出:
非递归实现:0
递归实现:14
可见,递归实现性能很差!