5.1 题目
有 n 步台阶,一次只能上 1 步或 2 步,共有多少种走法
5.2 递归
- n = 1
- 一步
- f(1) = 1
- n = 2
- 一步一步
- 直接 2 步
- f(2) = 2
- n = 3
- 先到达 f(1),然后从 f(1) 直接跨 2 步
- 先到达 f(2),然后从 f(2) 跨 1 步
- f(3) = f(1) + f(2)
- n = 4
- 先到达 f(2),然后从 f(2) 直接跨 2 步
- 先到达 f(3),然后从 f(3) 跨 1 步
- f(4) = f(2) + f(3)
- ……
- n = x
- 先到达 f(x-2),然后从 f(x-2) 直接跨 2 步
- 先到达 f(x-1),然后从 f(x-1) 跨 1 步
- f(x) = f(x-2) + f(x-1) ```java package s01.e05;
public class TestStep {
public int f(int n) {if (n < 1) {throw new IllegalArgumentException(n + "不能小于 1");}if (n == 1 || n == 2) {return n;}return f(n - 2) + f(n - 1);}
}
<a name="WDwIW"></a># 5.3 循环迭代- n = 1- 一步- f(1) = 1- n = 2- 一步一步- 直接 2 步- f(2) = 2- n = 3- 先到达 f(1),然后从 f(1) 直接跨 2 步- 先到达 f(2),然后从 f(2) 跨 1 步- one 保存最后走一步- two 保存最后走两步- f(3) = two + one- f(3) = f(1) + f(2)- two = f(1)- one = f(2)- n = 4- 先到达 f(2),然后从 f(2) 直接跨 2 步- 先到达 f(3),然后从 f(3) 跨 1 步- f(4) = two + one- f(4) = f(2) + f(3)- two = f(2)- one = f(3)- ......- n = x- 先到达 f(x-2),然后从 f(x-2) 直接跨 2 步- 先到达 f(x-1),然后从 f(x-1) 跨 1 步- f(x) = two + one- f(x) = f(x-2) + f(x-1)- two = f(x-2)- one = f(x-1)```javapackage s01.e05;public class TestStep2 {public int loop(int n) {if (n < 1) {throw new IllegalArgumentException(n + "不能小于 1");}if (n == 1 || n == 2) {return n;}int one = 2; // 初始化为走到第二级台阶的走法int two = 1; // 初始化为走到第一级台阶的走法int sum = 0;for (int i = 3; i < n; i++) {// 最后跨 2 步 + 最后跨 1 步的走法sum = two + one;two = one;one = sum;}return sum;}}
5.4 小结
- 方法调用自身称为递归,利用变量的原值推出新值称为迭代。
- 递归
- 优点:大问题转化为小问题,可以减少代码量,同时代码精简,可读性好
- 缺点:递归调用浪费了空间,而且递归太深容易造成堆栈的溢出
- 迭代
- 优点:代码运行效率好,因为时间只因循环次数增加而增加,而且没有额外的空间开销
- 缺点:代码不如递归简洁,可读性好
