空间换时间,把递归的时间复杂度降低到O(2n)
2012-09-05 08:41
309 查看
递归算法的时间复杂度除非只有前两项,否则都不是线性的,并且相当耗费内存。我们用最常见的的fibonacci数列来说明:
这是一种最常见的写法,这种写法极其耗费内存,当参数n大于30时,就会明显感觉到花的时间比较长,如果n等于100,浏览器极有可能会崩溃掉。
我们来分析一下耗费内存和时间原因:先将要计算的变量值存到堆栈中,不停地使用栈,保存现场,直到递归结束条件满足时,才从堆栈中取出要计算的变量值,再一一恢复现场,计算得到最终结果。
我们通过一张图来看一下这个递归的调用过程:
我们可以看到,当n为4时,一共进行了12步运算,其中第6、8、9、10、11步是重复的。正是这些重复的地方造成了这个递归的低效。
既然找到了原因所在,那么我们怎么来改进呢?
从原因下手,原因是之前的计算结果没有保存,造成了重复计算,那么我们就把之前的计算结果用一个变量保存起来,修改后的代码如下:
这里我们引入了一个变量temp来存储前面的计算结果,这种做法就是以空间换时间的做法。由于递归总是要到达最底层,然后再回到最顶层,所以时间复杂度最小为O(2n),我们修改后的递归算法时间复杂度即为O(2n)。
最后,我们来测试一下计算n为100的情况时间和计算次数:
我们可以看到,时间很短,计算次数只有199次。如果用没有优化的代码,我的浏览器会崩溃掉。
希望本文对大家有所帮助,欢迎留言讨论。
本文首发博客园:http://jscode.cnblogs.com,转载请注明出处。
function fibonacci(n){ if( n === 0 || n === 1){ return n; } else { return fibonacci(n - 1) + fibonacci(n - 2); } }
这是一种最常见的写法,这种写法极其耗费内存,当参数n大于30时,就会明显感觉到花的时间比较长,如果n等于100,浏览器极有可能会崩溃掉。
我们来分析一下耗费内存和时间原因:先将要计算的变量值存到堆栈中,不停地使用栈,保存现场,直到递归结束条件满足时,才从堆栈中取出要计算的变量值,再一一恢复现场,计算得到最终结果。
我们通过一张图来看一下这个递归的调用过程:
我们可以看到,当n为4时,一共进行了12步运算,其中第6、8、9、10、11步是重复的。正是这些重复的地方造成了这个递归的低效。
既然找到了原因所在,那么我们怎么来改进呢?
从原因下手,原因是之前的计算结果没有保存,造成了重复计算,那么我们就把之前的计算结果用一个变量保存起来,修改后的代码如下:
var fibonacci=(function(){ var temp={}, value; function f(n){ if(n in temp){ value=temp ; } else { if( n === 0 || n === 1){ value = n; } else { value = f(n - 1) + f(n - 2); } temp = value; } return value; } return f; })();
这里我们引入了一个变量temp来存储前面的计算结果,这种做法就是以空间换时间的做法。由于递归总是要到达最底层,然后再回到最顶层,所以时间复杂度最小为O(2n),我们修改后的递归算法时间复杂度即为O(2n)。
最后,我们来测试一下计算n为100的情况时间和计算次数:
我们可以看到,时间很短,计算次数只有199次。如果用没有优化的代码,我的浏览器会崩溃掉。
希望本文对大家有所帮助,欢迎留言讨论。
本文首发博客园:http://jscode.cnblogs.com,转载请注明出处。
相关文章推荐
- 空间换时间,把递归的时间复杂度降低到O(2n)
- 数据结构::递归时间复杂度的计算
- 函数的递归调用的时间复杂度
- 递归树求解递归算法的时间复杂度
- 二分查找与斐波那契数递归与非递归的时间复杂度与空间复杂度
- 传输速率的比较 快排的最好和最坏的时间复杂度比较 递归深度的问题 ackerman函数
- 求递归算法时间复杂度:递归树
- 【开放 5月18日 发布】:子数组的最大乘积问题_____问题简单,请思考如何逐步降低时间复杂度,跟帖回复,群内讨论.
- 求递归算法时间复杂度:递归树
- PHP 用数组降低程序的时间复杂度
- 递归式求时间复杂度的递归树的方法举例说明
- PHP 中巧用数组降低程序的时间复杂度
- 作业:递归实现插入排序和在o(nlgn)时间复杂度内寻找和为定值的两个元素
- [算法] 使用“复杂”的数据结构降低时间复杂度
- 写出斐波那契数列的递归与迭代代码,并分析时间和空间复杂度。
- 求递归算法时间复杂度:递归树
- 递归的时间复杂度计算
- 求递归方式的时间复杂度【转】
- !HDU 1506 Largest Rectangle in a Histogram-dp|单调队列-(dp降低时间复杂度)
- PHP 中巧用数组降低程序的时间复杂度