剑指offer 2.4 递归和循环-斐波那契数列计算改进
2014-08-10 16:18
344 查看
2.4.2 递归和循环
递归:函数内调用这个函数自身
循环:通过设置计算的初始值及终止条件,在一个范围内重复与运算
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/c8b733c3af864168935f1f2e6c5f3dbd/clipboard.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/c19fae5d953e261d1699e923e4c298db)
在树的遍历中,递归的实现明显比循环简单得多。
在面试的时候,如果没有特别要求,要尽量使用递归。
递归的缺陷:
递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而往栈中压入数据和弹出数据都需要时间。
递归中很多计算都是重复的:本质是把一个问题分解成两个或者多个小问题。如果多个小问题存在相互重叠的部分,那么就存在重复计算。
===
调用栈溢出:每个进程的栈的容量是有限的。当递归调用的层级太多事,就会超出栈的容量,从而导致溢出。如上述求和例子,如果求1~5000,可能会出错。
面试题9:斐波那契数列
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/d4ffe1e53bdc48cab4aff55a60d9a8a5/clipboard.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/5fcab6cabb40d6770cd47a8d72e8481f)
不好的实现:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/28778e95d93e862e2d94f3410dfa0aa9)
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/158905bf204d46a08db91e81d6050970/clipboard.png)
分析:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/7fc221ae933f6c360d0f54c1ac27218c)
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/01bb689334a449b393705072e8a3d066/clipboard.png)
大量重复计算,随着N的增大,重复计算量更大。
改进O(N):
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/e37d594e55754c6bb830dfa16dd5415e/clipboard.png)
采用自下而上的方法,首先根据f(0)f(1) 求出f(2), 再根据f(1)f(2)求出f(3)......
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/af3a0ad1362cf9dc923d1b2f257fedf2)
继续改进O(logN):
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/dbcb4596d67b4bbda8cacc2ac95f76a7/clipboard.png)
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/140a2f63f9304a65b6c623f200006d8c/clipboard.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/70763457a081e445a87c016a8a545db6)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201408/10/50e7b965bfec0ea625a5c650acdd1e63)
1个台阶:1种
2个台阶:2种,跳一个台阶、跳两个台阶
3个
4个
N个: 第一次跳一个,剩下n-1个台阶的跳法总数
第一次跳2个,剩下N-2个台阶的跳法总数
斐波那契~~~~
递归:函数内调用这个函数自身
循环:通过设置计算的初始值及终止条件,在一个范围内重复与运算
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/c8b733c3af864168935f1f2e6c5f3dbd/clipboard.png)
在树的遍历中,递归的实现明显比循环简单得多。
在面试的时候,如果没有特别要求,要尽量使用递归。
递归的缺陷:
递归由于是函数调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址及临时变量,而往栈中压入数据和弹出数据都需要时间。
递归中很多计算都是重复的:本质是把一个问题分解成两个或者多个小问题。如果多个小问题存在相互重叠的部分,那么就存在重复计算。
===
调用栈溢出:每个进程的栈的容量是有限的。当递归调用的层级太多事,就会超出栈的容量,从而导致溢出。如上述求和例子,如果求1~5000,可能会出错。
面试题9:斐波那契数列
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/d4ffe1e53bdc48cab4aff55a60d9a8a5/clipboard.png)
不好的实现:
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/158905bf204d46a08db91e81d6050970/clipboard.png)
分析:
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/01bb689334a449b393705072e8a3d066/clipboard.png)
大量重复计算,随着N的增大,重复计算量更大。
改进O(N):
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/e37d594e55754c6bb830dfa16dd5415e/clipboard.png)
采用自下而上的方法,首先根据f(0)f(1) 求出f(2), 再根据f(1)f(2)求出f(3)......
继续改进O(logN):
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/dbcb4596d67b4bbda8cacc2ac95f76a7/clipboard.png)
![](http://blog.csdn.net/bluegreen315/article/details/file:/C:/Users/Administrator/AppData/Local/YNote/Data/zccc@mail.ustc.edu.cn/140a2f63f9304a65b6c623f200006d8c/clipboard.png)
1个台阶:1种
2个台阶:2种,跳一个台阶、跳两个台阶
3个
4个
N个: 第一次跳一个,剩下n-1个台阶的跳法总数
第一次跳2个,剩下N-2个台阶的跳法总数
斐波那契~~~~
相关文章推荐
- 剑指offer-09:递归和循环,斐波那契数列
- 剑指offer:(7)递归和循环:斐波那契数列
- 【剑指offer】【斐波那契数列 】递归还是循环
- 【剑指offer】2.4.2递归和循环——面试题9:斐波那契数列
- 【剑指offer】斐波那契数列--递归及循环剖析
- 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)
- 剑指offer--斐波那契数列-递归
- (C++)剑指offer-9:变态跳台阶(递归和循环)
- 剑指offer——树的镜像(基础,同样是考察遍历树的循环或递归)
- 剑指offer----斐波那契数列的实现--递归和迭代
- 【剑指offer】递归循环两种方式反转链表
- 剑指offer 07-10 斐波那契数列类型题目的动态规划解题方法(递归方法)
- 剑指offer_递归与循环---扑克牌顺子
- 剑指offer--循环递归
- 【剑指offer】递归循环两种方式反转链表
- 剑指offer: 矩形覆盖(循环与递归)
- (C++)剑指offer-8:跳台阶(递归和循环)
- 剑指offer 算法 (递归与循环)
- 剑指offer面试题:求二叉树的镜像(递归、循环解法及测试用例)
- 【剑指offer】递归循环两种方式反转链表