递归 - 空间复杂度 

在本文中, 我们将讨论如何分析递归算法的空间复杂度.
在计算递归算法的空间复杂度时,最需要考虑的两个部分就是: 递归相关空间 (recursion related space)和非递归相关空间(non-recursion related space).

递归相关空间


递归相关空间指的是递归直接产生的内存开销,也就是在递归调用过程中开辟的堆栈内存空间。为了完成一个典型的函数调用,系统中在开辟内存空间时,会存放一下3个重要的数据信息:
  1. 调用函数的返回地址. 一旦程序调用结束,需要这个地址返回, 即程序调用结束进行下一步的地址;
  2. 该调用函数所需要的参数;
  3. 调用函数的内部变量.
尽管堆栈是在递归调用时产生的最小消耗. 旦只要调用过程结束,这些空间也会被释放掉。 
对于递归算法,函数的调用将会持续产生调用链,直至调用到基本型 (base case) (亦称作. bottom case).这意味着每个函数的调用也是逐步累积的.
对于递归算法, 如果没有其他的内存消耗, 这个算法的空间上限就是该递归调用直接产生的内存开销。
还是拿练习 printReverse说事,我们每次调用只是打印了一个字符,所以在递归调用之外我们没有用掉其他的内存开销, .对于每一次的递归调用, 假设需要一个固定常量的空间. 那么根据前面的分析,他会调用 n 次函数链,  n 就是输入的字串长度. 所以该算法的空间复杂度即为 {\mathcal{O}(n)}O(n).
为了更好地说明, 对于递归调用序列 f(x1) -> f(x2) -> f(x3) 的执行步骤序列以及堆栈的布局如下图所示:
 f(x1) 将会被分配一定额外的空间以便调用f(x2). 对于 f(x2)调用f(x3).时候的内存操作也是同样类型的情况,直到 f(x3),的调用到达了基本型, 当到达 f(x3).时,不在分配额外空间。
这种调用机制导致有时分配给堆栈的空间有时超出内存限制,会导致一种程序崩溃的情况,叫做栈溢出(stack overflow),所以当设计采用这种递归调用机制的程序时,首要考虑的就是输入量是否会导致溢出情况的发生。
 

非递归相关空间


显而易见, 所谓非递归相关空间即与递归调用链过程中不直接相关的内存开销, 比如为全局变量所分配的空间(一般情况下都存放在堆heap中).
不论是否是递归程序,在执行下一个子程序之前总需要一个全局变量来存放输入的数据。  同样对于调用函数的返回值也需要开辟空间来存放.后者的一种情况就是我们前面讨论过的 记忆化 处理方式. 例如在处理斐波那契额数列的记忆化递归算法中, 我们使用一个map来存储每次递归调用返回的结果值. 因此, 在计算该算法的空间复杂度的时候, 我们同时也需要考虑记忆化操作所带来的空间成本.  
 
 
 
 
 
 
 
 
 
 

LeetCode递归 -2(Recursion) 培训专题 讲解文章翻译 (附链接) (2019-04-09 15:50)的更多相关文章

  1. LeetCode 递归(Recursion) 培训专题 讲解文章翻译 (附链接)

     递归 - 时间复杂度 在本文中, 我们主要介绍如何分析递归算法程序中的时间复杂度.. 在一个递归程序中, 它的时间复杂度 O(T) 一般来说就是他总共递归调用的次数 (定义为 R) 以及每次调用时所 ...

  2. Activity Process Task Application 专题讲解

    Activity Process Task Application 专题讲解 Activity.和进程 为了阅读方便,将文档转成pdf http://files.cnblogs.com/franksu ...

  3. 程序员的算法课(3)-递归(recursion)算法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  4. Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences)

    Leetcode之深度优先搜索&回溯专题-491. 递增子序列(Increasing Subsequences) 深度优先搜索的解题详细介绍,点击 给定一个整型数组, 你的任务是找到所有该数组 ...

  5. Leetcode之深度优先搜索&回溯专题-980. 不同路径 III(Unique Paths III)

    Leetcode之深度优先搜索&回溯专题-980. 不同路径 III(Unique Paths III) 深度优先搜索的解题详细介绍,点击 在二维网格 grid 上,有 4 种类型的方格: 1 ...

  6. Leetcode之深度优先搜索&回溯专题-679. 24 点游戏(24 Game)

    Leetcode之深度优先搜索&回溯专题-679. 24 点游戏(24 Game) 深度优先搜索的解题详细介绍,点击 你有 4 张写有 1 到 9 数字的牌.你需要判断是否能通过 *,/,+, ...

  7. Leetcode之深度优先搜索&回溯专题-638. 大礼包(Shopping Offers)

    Leetcode之深度优先搜索&回溯专题-638. 大礼包(Shopping Offers) 深度优先搜索的解题详细介绍,点击 在LeetCode商店中, 有许多在售的物品. 然而,也有一些大 ...

  8. Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands)

    Leetcode之并查集专题-765. 情侣牵手(Couples Holding Hands) N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并 ...

  9. Leetcode之并查集专题-684. 冗余连接(Redundant Connection)

    Leetcode之并查集专题-684. 冗余连接(Redundant Connection) 在本问题中, 树指的是一个连通且无环的无向图. 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2 ...

随机推荐

  1. linux tail 命令详解!Linux 文件内容查看工具介绍

    转:http://blog.csdn.net/carzyer/article/details/4759593 1.cat 显示文件连接文件内容的工具: cat 是一个文本文件查看和连接工具.查看一个文 ...

  2. cocos2dx -lua 面向对象-转

    转自:http://www.himigame.com/lua-game/1282.html 上一篇中,向童鞋们介绍了如何自定义类binding到Lua中供给使用的教程,那么本篇将介绍利用OOP思想在在 ...

  3. JVM类加载的那些事

    原文出处: 占小狼 前言 Java源代码被编译成class字节码,最终需要加载到虚拟机中才能运行.整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载7个阶段.   加载 1.通过一个类的全限 ...

  4. C#的Xamarin开发小米盒子应用并以WCF实现微信通知

    对于熟悉C#语言的开发人员而言,用Xamarin开发Android应用也是一个不错的选择.小米盒子是Android系统.当然也就能够使用Xamarin来开发.首选来看效果图. watermark/2/ ...

  5. LinkedIn是如何优化Kafka的

    作者 张卫滨                发布于        2015年9月21日   转载 在LinkedIn的数据基础设施中,Kafka是核心支柱之一.来自LinkedIn的工程师曾经就Kaf ...

  6. javascript快速入门11--正则表达式

    正则表达式可以: 测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证 替换文本.可以在文档中使用一个正则表达式来标 ...

  7. OOP几大原则【转】

    设计模式遵循的一般原则: 1.开-闭原则(Open-Closed Principle, OCP):一个软件实体应当对扩展开发,对修改关闭.说的是,再设计一个模块的时候,应当使这个模块可以在不被修改的前 ...

  8. fetch的用法

    fetch api是被设计用来替换XmlHttpRequest的,详细用法如下: http://javascript.ruanyifeng.com/bom/ajax.html#toc27

  9. Unity网游开发生存指南—蒸汽之城

    Posted by amy on 2013.03.07 文 / 王楠(梦加网络 游戏制作人) 前段时间关于Unity是否适合国内手游/网游创业团队的讨论非常火爆,本文从<蒸汽之城>的开发历 ...

  10. axios 取消请求

    解决思路 在发送第二次请求的时候如果第一次请求还未返回,则取消第一次请求,以保证后发送的请求返回的数据不会被先发送的请求覆盖. axios官方文档取消请求说明 方法一: const CancelTok ...