本题为
LeetCode第70题爬楼梯
,题目如下:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
当剩下 1 个台阶的时候只有 1 种方法
1==>1
当剩下 2 个台阶的时候只有 2 种方法
1==>1 或者 2
当剩下 3 个台阶的时候只有 3 种方法
1==>1==>1 或者 1==>2 或者 2==>1
当剩下 4 个台阶的时候只有 5 种方法
1==>1==>1==>1 || 1==>2==>1 || 1==>1==>2 || 2==>1==> || 2==>2
.
.
.
推到 可知 f(3)=f(2)+f(1)=2+1 f(4)=f(3)+f(2)=3+2 所以 可以推出
f(n)=f(n-1)+f(n-2)
方法一:递归
代码:
public class ClimbStairs {
public static void main(String[] args) {
int step=ClimbMethods(5);
System.out.println(step);
int step2= ClimbMethods(10);
System.out.println(step2);
}
public static int ClimbMethods(int n){
if(n==2)return 2;
if(n==1) return 1;
return ClimbMethods(n-2)+ClimbMethods(n-1);
}
}
但是 经过分析 我们 无论哪种方法 都会有重复的计算
例如: 我们计算 6个台阶的时候
f(6)=f(5)+f(4)
f(5)=f(3)+f(4) f(4)=f(3)+f(2)
f(4)=f(3)+f(2) + f(3)=f(2)+f(1) f(3)=f(2)+f(1) + f(2)
这里 f(3) f(4) 多次重复计算 有损于计算时间 所以我们可以将我们计算过的值 存入Map集合当中 如果有过直接取值 如果没有再去计算存储
import java.util.HashMap;
import java.util.Map;
public class ClimbStairs {
public static void main(String[] args) {
int step=ClimbMethods(5);
System.out.println(step);
int step2= ClimbMethods(10);
System.out.println(step2);
}
private static Map<Integer,Integer> resultMap=new HashMap();
public static int ClimbMethods(int n){
if(n==2)return 2;
if(n==1) return 1;
if(resultMap.get(n)==null){
int result=ClimbMethods(n-2)+ ClimbMethods(n-1);
resultMap.put(n,result);
return result;
}else{
System.out.println(resultMap);
return resultMap.get(n);
}
}
}
方法二:循环
由上图 可知
f(6)=f(5)+f(4)
f(5)=f(3)+f(4) f(4)=f(3)+f(2)
f(4)=f(3)+f(2) + f(3)=f(2)+f(1) f(3)=f(2)+f(1) + f(2)
下一次开始 用的 是上一次的值 根据这条 我们可以写一个循环
思路:
3个变量 pre=1 prepre=2 result=0
pre 为 f(n-1)的值 prepre为 f(n-2)的值
result 为最终结果
循环 条件应为 n初始值为 3 每次+1 知道 和 最终台阶数 6相等为止
结果 result 为 f(n-1)+f(n-2)= pre+prepre
替换
pre 为 prepre 值
prepre值为 result
public static int ClimbForMethods(int n){
if(n==2)return 2;
if(n==1) return 1;
int pre=1;
int prepre=2;
int result=0;
for(int i=3;i<=n;++i){
result=pre+prepre;
pre=prepre;
prepre=result;
}
return result;
}
调用