再不疯狂就老了吗

导航

爬楼梯问题java实现

问题:

  从楼上走到楼下有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)); //可以计算值
}

}

 

posted on 2020-04-02 23:03  再不疯狂就老了吗  阅读(652)  评论(0编辑  收藏  举报