问题一
递归解法
设f(n)=x,表示有n个台阶时,有x中走法
- n=1,一步 f(1)=1
- n=2,一步一步 或者 直接两步 f(2)=2
- n=3,
- 先到达f(1),然后f(1)直接跨2步。
- 先到达f(2),然后f(2)跨1步。
- 即 f(3) = f(1)+f(2),表示,到f(1)的走法+到f(2)的走法
- n=4,
- 先到达f(2),然后从f(2)直接跨2步
- 先到达f(3),然后f(3)跨1步
- 即 f(4) = f(2)+f(3),表示到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),表示到f(x-2)的走法+到f(x-1)的走法 ```java public class Recursion { public static void main(String[] args) { final long start = System.currentTimeMillis(); System.out.println(“共有走法 “ + fun(40) + “ 种”); final long end = System.currentTimeMillis(); System.out.println(“总共耗时” + (end - start) + “ms”); }
private static int fun(int n) { if (n < 1) {
throw new IllegalArgumentException(n + "不能小于1");
} if (n == 1 || n == 2) {
return n;
} return fun(n - 2) + fun(n - 1); } }
// 结果 当n=40时 共有走法 165580141 种 总共耗时303ms
<a name="FWCQb"></a>### 循环迭代解法设f(n)=x,表示有n个台阶时,有x中走法<br />令 one保存最后走一步的方法,two保存最后走两步的方法- n=1,一步 f(1)=1- n=2,一步一步 或者 直接两步 f(2)=2- n=3,- 先到达f(1),然后f(1)直接跨2步。- 先到达f(2),然后f(2)跨1步。- 即 f(3) = f(1)+f(2),表示,到f(1)的走法+到f(2)的走法 two=f(1),one=f(2)- n=4,- 先到达f(2),然后从f(2)直接跨2步- 先到达f(3),然后f(3)跨1步- 即 f(4) = f(2)+f(3),表示到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)=f(x-2)+f(x-1),表示到f(x-2)的走法+到f(x-1)的走法two=f(x-2),one=f(x-1)```javapublic class LoopIterate {public static void main(String[] args) {final long start = System.currentTimeMillis();System.out.println("共有走法 " + loop(40) + " 种");final long end = System.currentTimeMillis();System.out.println("总共耗时" + (end - start) + "ms");}private static int loop(int n) {if (n < 1) {throw new IllegalArgumentException(n + "不能小于1");}if (n == 1 || n == 2) {return n;}// 最后走一步的方法是f(2),其有2种走法 即 初始化为走到第二级台阶的走法int one = 2;// 最后走两步的方法是f(1),其有1种走法 即 初始化为走到第一级台阶的走法int two = 1;// 一共的走法int sum = 0;for (int i = 3; i <= n; i++) {// 最后走1步 + 最后走2步的走法 , 记录下到i个台阶时的总走法sum = one + two;// 到 i+1个台阶时,需要用到的还需要走两步的走法,就是i个台阶时的还需要走一步的走法two = one;// 到 i+1个台阶时,需要用到的还需要走一步的走法,就是i个台阶时的总走法one = sum;}return sum;}}结果共有走法 165580141 种总共耗时0ms
总结
- 方法调用自身称其为递归,利用变量的原值推出新值称为迭代
- 递归
- 优点:大问题转化为小问题,减少代码量,可读性好
- 缺点:递归浪费空间,递归太深容易造成堆栈溢出。
- 迭代
- 优点:代码运行效率好,因为时间只因循环次数增加而增加,而且没有额外的空间开销;
- 缺点:代码可读性没有递归强,不够简洁
