递归与迭代
编程题:求n步台阶,一次只能上1步或2步,一共有几种走法???
1. 递归
台阶数 | 实现方法 | 等式 |
---|---|---|
n=1 | 一步 | f(1)=1 |
n=2 | 1> 一步一步 2> 直接两步 | f(2)=2 |
n=3 | 1>先到达f(1) ,然后从f(1) 直接跨2步 2>先到达f(2),然后从f(2)跨1步 | f(3)=f(1)+f(2) |
n=4 | 1>先到达f(2) ,然后从f(2) 直接跨2步 2>先到达f(3),然后从f(3)跨1步 | f(4)=f(2)+f(3) |
… | … | … |
n=x | 1>先到达f(x-2) ,然后从f(x-2) 直接跨2步 2>先到达f(x-1),然后从f(x-1)跨1步 | f(x)=f(x-2)+f(x-1) |
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);
}
2. 循环迭代
one 保存最后一步走法;two 保存最后两步走法;
台阶数 | 实现方法 | 等式 |
---|---|---|
n=1 | 一步 | f(1)=1 |
n=2 | 1> 一步一步 2> 直接两步 | f(2)=2 |
n=3 | 1>先到达f(1) ,然后从f(1) 直接跨2步 2>先到达f(2),然后从f(2)跨1步 | f(3)=two+one f(3)=f(1)+f(2) two=f(1) one=f(2) |
n=4 | 1>先到达f(2) ,然后从f(2) 直接跨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 | 1>先到达f(x-2) ,然后从f(x-2) 直接跨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) |
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;
}
小结
方法调用自身称为递归,利用变量的原值推出新值称为迭代
递归
- 优点:大问题转化为小问题,可以减少代码量,同时代码精简,可读性好;
- 缺点:递归调用浪费了空间,而且递归太深容易造成堆栈的溢出。
迭代
- 优点:代码运行效率好,因为时间只因循环次数增加而增加,而且没有额外的空间开销;
- 缺点:代码不如递归简洁,可读性好