问题:
从楼上走到楼下有n个台阶,每一步有3中走法:走1个台阶,走2个台阶,走3个台阶。
如:
当有1个台阶时,有1种走法
当有2个台阶时,有2种走法
当有3个台阶时,有4钟走法
求:
当有4个台阶时,有几种走法?
当有5个台阶时,有几种走法?
当有100个台阶时,有几种走法?
请设计程序计算,对于给定的n个台阶,有几种走法?
解答思路
1.想到类似斐波那契数列算法,得出F(n)=F(n-1)+F(n-2)+F(n-3),采用递归的办法实现,如下面calucate1方法可实现。
但有个问题是随着楼梯台阶增多,计算量会成指数增长,时间复杂度会大大增加。
2.采用excel计算的思路,在excel中,重上往下先定义4个值,如
a1=1,a2=2,a3=4,a4=7,选中a2,a3,a4,采用公式F(n)=F(n-1)+F(n-2)+F(n-3)的形式,计算a5到a100的值
如下面calucate2方法可实现。
这样实现不太好,数组有可能太长
3.采用定长数组,循环替换的方式,参考calucate3方法可实现。
还有一个问题,当n=100时,数值会很大,在java中涉及到大数计算
4.采用BigInteger,参考calucate4方法可实现。
备注:
先分享我对这个问题的思考,抛砖引玉,欢迎大家讨论,里面还有什么问题,还可以怎么优化
import java.math.BigInteger;
public class Stair {
public static int calucate1(int i){
if(i<=0){
return 0;
}
switch (i){
case 1:
return 1;
case 2:
return 2;
case 3:
return 4;
default:
return calucate1(i-1)+calucate1(i-2)+calucate1(i-3);
}
}
public static int calucate2(int i){
if(i<=0){
return 0;
}
switch (i){
//第1个台阶
case 1:
return 1;
//第2个台阶
case 2:
return 2;
//第3个台阶
case 3:
return 4;
//第i个台阶
default:
int[] data=new int[i];
data[0]=1;
data[1]=2;
data[2]=4;
for(int j=4;j<=i;j++){
//计算第j个台阶时有多少种走法
data[j-1]=data[j-2]+data[j-3]+data[j-4];
}
//返回第i个台阶时有多少种走法
return data[i-1];
}
}
public static int calucate3(int i){
if(i<=0){
return 0;
}
switch (i){
//第1个台阶
case 1:
return 1;
//第2个台阶
case 2:
return 2;
//第3个台阶
case 3:
return 4;
//第i个台阶
default:
//初始化第一个,第二个,第三个台阶时的走法
int[] data={1,2,4};
for(int j=4;j<=i;j++){
//定义数组下标值
int index= (j-1)%3;
//计算数值
int temp=data[0]+data[1]+data[2];
//替换目标下标值所在位置的数值
data[index]=temp;
}
return data[(i-1)%3];
}
}
public static BigInteger calucate4(int i){
if(i<=0){
return new BigInteger("0");
}
switch (i){
//第1个台阶
case 1:
return new BigInteger("1");
//第2个台阶
case 2:
return new BigInteger("2");
//第3个台阶
case 3:
return new BigInteger("4");
//第i个台阶
default:
//初始化第一个,第二个,第三个台阶时的走法
BigInteger[] data={new BigInteger("1"),new BigInteger("2"),new BigInteger("4")};
for(int j=4;j<=i;j++){
//定义数组下标值
int index= (j-1)%3;
//计算数值
BigInteger temp=data[0].add(data[1]).add(data[2]);
//替换目标下标值所在位置的数值
data[index]=temp;
}
return data[(i-1)%3];
}
}
public static void main(String[] args) {
System.out.println("---------------------1------------------------");
//采用递归的思路
System.out.println(calucate1(4)); //7
System.out.println(calucate1(5)); //13
System.out.println(calucate1(19)); //66012
// System.out.println(calucate1(100)); //递归层级计算次数太多,代码执行起来时间复杂度巨大
System.out.println("---------------------2------------------------");
//excel从上往下拖动的思路
System.out.println(calucate2(4)); //7
System.out.println(calucate2(5)); //13
System.out.println(calucate2(19)); //66012
System.out.println(calucate2(100)); //随着台阶数量增长,数组长度也增长,浪费空间
System.out.println("---------------------3------------------------");
//采用数组值交替计算的思路
System.out.println(calucate3(4)); //7
System.out.println(calucate3(5)); //13
System.out.println(calucate3(19)); //66012
System.out.println(calucate3(100)); //可以计算值
//解决大数值计算的问题
System.out.println("---------------------4------------------------");
System.out.println(calucate4(4)); //7
System.out.println(calucate4(5)); //13
System.out.println(calucate4(11)); //66012
System.out.println(calucate4(1000)); //可以计算值
}
}