引言

开始之前,先来看一个著名的数列--斐波拉契数列,该数列是以兔子繁殖为问题引入的,问题如下:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,则每个月的兔子总数为多少?为了方便描述,假设第n个月的兔子数量为f(n),则f(n)规律如下:

  f(1)=1  f(2)=1  f(3)=2  f(4)=3  f(5)=5 ...  f(n)=f(n-2)+f(n-1)

问题

常见的楼梯问题个人理解成斐波拉契数列的衍生问题,在规律上与斐波拉契数列相同或相似,问题如下:有n(n为正整数)阶楼梯,每次可以上1阶或者2阶,一共有多少种上法?

分析

对于楼梯问题, 可以对照斐波拉契数列的规律去分析,即用数学数列的思维,对n取有限值的情况进行列举,寻找规律:

   f(1)=1  n=1

   f(2)=2  n=2

   f(3)=3  n=3

   f(4)=5  n=4

总结规律:

   f(1)=1 
   f(2)=2
   f(n)=f(n-2)+f(n-1) (n>2)

可以带入n=5,验证规律率是否正确

 

以下思路为个人理解,仅供参考:

因为每次可以走1阶或者2阶,可以认为n=1或n=2是特殊情况:

  当n=1时,只能采取走1阶的方式,共1种

  当n=2时,与n=1相比,多了每次走2阶的方式,所以走法+1,共2种

  当n=3时,可以看成把两个阶梯合并为一个,构造出n=2的情况,剩下1个未合并,即n=1的情况,所以f(3)=f(1)+f(2),共3种

  当n=4时,可以看成把两个阶梯合并为一个,构造出n=3的情况,剩下2个未合并,即n=2的情况,所以f(4)=f(2)+f(3),共5种

以此类推:
  f(1)=1
  f(2)=2
  f(n)=f(n-2)+f(n-1) (n>2)

结论

f(1)=1   (n=1)

f(2)=2  (n=2)

f(n)=f(n-2)+f(n-1)  (n>2)

 

在java中实现

 有了解决问题的思路,写代码就简单了,根据以上思路,在java中使用递归来解决此类问题,这里只提供实现方法:

//计算n阶楼梯,每次上1或2阶,共总多少种走法
private int stairsWays(int stairsNums) {
  if (stairsNums <= 0) {
    return 0;
  }
  if (stairsNums == 1) {
    return 1;
  }
  if (stairsNums == 2) {
    return 2;
  }
  return stairsWays(stairsNums - 1) + stairsWays(stairsNums - 2);
}

//计算n阶楼梯,每次上1或2或3阶,共总多少种走法
private int stairsWaysPlus(int stairsNums) {
  if (stairsNums <= 0) {
    return 0;
  }
  if (stairsNums == 1) {
    return 1;
  }
  if (stairsNums == 2) {
    return 2;
  }
  if (stairsNums == 3) {
    return 4;
  }
  return stairsWaysPlus(stairsNums - 3) + stairsWaysPlus(stairsNums - 2)+ stairsWaysPlus(stairsNums - 1);
}