递归与循环在函数求解中会经常使用,但是各自有各自的优缺点
递归:代码小,但是不优化的话时间空间占用较大
题目9:斐波那契数列
问题描述:
写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。
解题思路:
- 常规解法,按照递推公式,f(n) = f(n-1)+f(n-2)实现递归,但是会出现就很多重复计算节点;
- 实用解法:将计算的的结果保存下来,下次计算时调用即可;
- 进阶解法:从下往上计算 f(0)和f(1)算出f(2),再由f(1)和f(2) 算出f(3)
实现代码:
普通解法:
public long Fibonacci(int n) {
if(n<=0)
return 0;
if(n==1)
return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
复杂度为O(n的算法)
public long Fibonacci2(int n) {
int result[] = {0,1};
if(n<2)
return result[n];
long fibNMinusOne = 1;
long fibNMinusTwo = 0;
long fibN = 0;
for(int i =2;i<-n;i++) {
fibN = fibNMinusOne+fibNMinusTwo;
fibNMinusTwo = fibNMinusOne;
fibNMinusOne = fibN;
}
return fibN;
}
时间复杂度为O(logn)但是不实用的解法(比较难)
利用数学公式
求矩阵的乘方
利用递归的思路计算乘方,即可将时间复杂度降低为O(longn)
解法比较:
- 第一种使用递归的解法,效率较低
- 第二种将递归转换为循环,提高了空间效率;
- 第三种代码较为复杂,隐含的时间常数大;
题目9-2青蛙跳台问题
题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
题目分析:
当只有一级台阶时,只有一种选择,当有两级台阶时有2种,1、分两次跳 2、一次跳两格,当为n时,可以看作第一次跳一级,后面的跳法f(n-1);第二次跳2级,此时后面跳法f(n-2),因此n级台阶的不同跳法总数就是f(n) = f(n-1)+f(n-2),因此转换为斐波那契数列Fibonacci Array
题目9-3 青蛙跳台阶
题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
题目分析:
除了必须到达最后一级台阶,第1级到第n-1级台阶都可以有选择的跳,也就是说对于这n-1个台阶来说,每个台阶都有跳上和不跳上2种情况,所以一共有2^(n-1)种方法。