题目:
有n个台阶,每次只能走一个台阶或两个台阶,问 一共有多少种走法?
即 f(n) = ?
首先 先自己模拟下台阶的走法,以方便寻找其中的规律
台阶数 | 走法过程 | 结果 |
1 | 走1步 | 1种 |
2 | 走1步 走1步 走2步 | 2种 |
3 | 走1步 走1步 走1步 走1步 走2步 走2步 走1步 | 3种 |
4 | 走1步 走1步 走1步 走1步 走2步 走1步 走1步 | 5种 |
5 | 走1步 走1步 走1步 走1步 走1步 走1步 走1步 走1步 走2步 走1步 走1步 走2步 走1步 走1步 走2步 走1步 走1步 走2步 走1步 走1步 走1步 走2步 走1步 走2步 走2步 走2步 走1步 走1步 走2步 走2步 | 8种 |
通过表格中的模拟数据 我们不难发现,当台阶数>2的时候 结果 = 前两个台阶数的结果的 和
即:
台阶数=3时 结果 = 1+2
台阶数=4时 结果 = 2+3
。。。。
台阶数=n时 结果= f(n-2) + f(n-1)
这是我们已经发现了其中的奥秘,剩下的就是用代码进行实现了,
第一种 递归实现:
public static void main(String[] args) {
//台阶数
int n = 5;
System.out.println(f(5));
}
/**
* 递归计算方法
* @param i 台阶数
*/
private static int f(int i) {
if(i == 1 || i == 2){
return i;
}
return f(i-2) + f(i-1);
}
递归解析:
f方法为计算结果的方法,
1.先判断台阶数 是否为1或2,是的话直接返回 台阶数
2.如果>2 则按照公式 递归调用 f(n-2) + f(n-1)
优点:代码阅读逻辑性强,
缺点:效率低下,n数值越大,递归层级指数增长。
第二种,循环处理
既然我们已经知道了 要计算 台阶的走法只需要 当前台阶的上一个台阶的走法+上上个台阶的走法 之和 (1和2台阶数除外),那么我们是否可以在一个循环中去从第三级台阶开始 依次的往后遍历 并计算 前两个台阶的值呢?
我们先列出 随着台阶数的增长 走法的增长表 方便直观的展示
1 | 2 | 3 | 4 | 5 | 6 |
1 | 2 | 3(1+2) | 5(2+3) | 8(3+5) | 13(5+8) |
代码如下:
public static void main(String[] args) {
//台阶数
int n = 5;
System.out.println(f(n));
}
/**
* 计算
*
* @param n 台阶数
*/
private static int f(int n) {
if (n == 1 || n == 2) {
return n;
}
//初始化上个台阶 的走法数
int one = 2;
//初始化上上个台阶的走法数
int tow = 1;
//初始化当前台阶的走法数
int result = 0;
for (int i = 3; i <= n; i++) {
//当前台阶的走法数 = 上个台阶的走法数+上上个台阶的走法数
result = one + tow;
//循环中 往前进一步 需要重新复制上个台阶的走法数和上上个台阶的走法数
tow = one;
one = result;
}
return result;
}
解析:
难点主要在于 循环中
循环从第三台阶开始 先计算 第三台阶的 走法数量
result = one + tow
计算完并赋值给 result 表示当前台阶的走法数
随后 因为要计算下一个台阶的走法数 下一个台阶的走法数 = 当前台阶的走法数 + 上一个台阶的走法数
所以这里 我们需要
上上个台阶的走法数 tow = 上一个台阶的走法数
上一个台阶的走法数one = 当前台阶的走法数
随后进入下一个循环 再次计算当前台阶的走法数,再次重新复制 one和tow
直到i大于n 循环结束 result中保存的就是最后台阶的 走法数了