Hello 算法 1.1.0 Dart版24 图 2‑4 递归调用深度 在实际中,编程语言允许的递归深度通常是有限的,过深的递归可能导致栈溢出错误。 2. 尾递归 有趣的是,如果函数在返回前的最后一步才进行递归调用,则该函数可以被编译器或解释器优化,使其在空 间效率上与迭代相当。这种情况被称为尾递归(tail recursion)。 ‧ 普通递归:当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下 和操作。 ‧ 尾递归:求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。 第 2 章 复杂度分析 hello‑algo.com 25 图 2‑5 尾递归过程 Tip 请注意,许多编译器或解释器并不支持尾递归优化。例如,Python 默认不支持尾递归优化,因此即 使函数是尾递归形式,仍然可能会遇到栈溢出问题。 3. 递归树 当处理与“分治”相关的算法问题时,递归往往比迭代的 暂存数据:用于保存算法运行过程中的各种常量、变量、对象等。 ‧ 栈帧空间:用于保存调用函数的上下文数据。系统在每次调用函数时都会在栈顶部创建一个栈帧,函数 返回后,栈帧空间会被释放。 ‧ 指令空间:用于保存编译后的程序指令,在实际统计中通常忽略不计。 在分析一段程序的空间复杂度时,我们通常统计暂存数据、栈帧空间和输出数据三部分,如图 2‑15 所示。 图 2‑15 算法使用的相关空间 相关代码如下:0 码力 | 378 页 | 18.45 MB | 1 年前3
Hello 算法 1.2.0 简体中文 Dart 版24 图 2‑4 递归调用深度 在实际中,编程语言允许的递归深度通常是有限的,过深的递归可能导致栈溢出错误。 2. 尾递归 有趣的是,如果函数在返回前的最后一步才进行递归调用,则该函数可以被编译器或解释器优化,使其在空 间效率上与迭代相当。这种情况被称为尾递归(tail recursion)。 ‧ 普通递归:当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下 ‧ 尾递归:求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。 第 2 章 复杂度分析 www.hello‑algo.com 25 图 2‑5 尾递归过程 Tip 请注意,许多编译器或解释器并不支持尾递归优化。例如,Python 默认不支持尾递归优化,因此即 使函数是尾递归形式,仍然可能会遇到栈溢出问题。 3. 递归树 当处理与“分治”相关的算法问题时,递归往往比迭代的 暂存数据:用于保存算法运行过程中的各种常量、变量、对象等。 ‧ 栈帧空间:用于保存调用函数的上下文数据。系统在每次调用函数时都会在栈顶部创建一个栈帧,函数 返回后,栈帧空间会被释放。 ‧ 指令空间:用于保存编译后的程序指令,在实际统计中通常忽略不计。 在分析一段程序的空间复杂度时,我们通常统计暂存数据、栈帧空间和输出数据三部分,如图 2‑15 所示。 图 2‑15 算法使用的相关空间 相关代码如下:0 码力 | 378 页 | 18.46 MB | 10 月前3
Hello 算法 1.0.0 Dart版24 图 2‑4 递归调用深度 在实际中,编程语言允许的递归深度通常是有限的,过深的递归可能导致栈溢出错误。 2. 尾递归 有趣的是,如果函数在返回前的最后一步才进行递归调用,则该函数可以被编译器或解释器优化,使其在空 间效率上与迭代相当。这种情况被称为「尾递归 tail recursion」。 ‧ 普通递归:当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下 次求和操作。 ‧ 尾递归:求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。 第 2 章 复杂度分析 hello‑algo.com 25 图 2‑5 尾递归过程 � 请注意,许多编译器或解释器并不支持尾递归优化。例如,Python 默认不支持尾递归优化, 因此即使函数是尾递归形式,仍然可能会遇到栈溢出问题。 3. 递归树 当处理与“分治”相关的算法问题时,递归往往比迭代的 暂存数据:用于保存算法运行过程中的各种常量、变量、对象等。 ‧ 栈帧空间:用于保存调用函数的上下文数据。系统在每次调用函数时都会在栈顶部创建一个栈帧,函数 返回后,栈帧空间会被释放。 ‧ 指令空间:用于保存编译后的程序指令,在实际统计中通常忽略不计。 在分析一段程序的空间复杂度时,我们通常统计暂存数据、栈帧空间和输出数据三部分,如图 2‑15 所示。 图 2‑15 算法使用的相关空间 相关代码如下:0 码力 | 377 页 | 17.56 MB | 1 年前3
Hello 算法 1.0.0b5 Dart版23 图 2‑4 递归调用深度 在实际中,编程语言允许的递归深度通常是有限的,过深的递归可能导致栈溢出报错。 2. 尾递归 有趣的是,如果函数在返回前的最后一步才进行递归调用,则该函数可以被编译器或解释器优化,使其在空 间效率上与迭代相当。这种情况被称为「尾递归 tail recursion」。 ‧ 普通递归:当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下 执行一次求和操作。 ‧ 尾递归:求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。 第 2 章 复杂度分析 hello‑algo.com 24 图 2‑5 尾递归过程 请注意,许多编译器或解释器并不支持尾递归优化。例如,Python 默认不支持尾递归优化,因此即使函数 是尾递归形式,但仍然可能会遇到栈溢出问题。 3. 递归树 当处理与“分治”相关的算法问题时,递归往往比迭代 暂存数据:用于保存算法运行过程中的各种常量、变量、对象等。 ‧ 栈帧空间:用于保存调用函数的上下文数据。系统在每次调用函数时都会在栈顶部创建一个栈帧,函数 返回后,栈帧空间会被释放。 ‧ 指令空间:用于保存编译后的程序指令,在实际统计中通常忽略不计。 在分析一段程序的空间复杂度时,我们通常统计暂存数据、栈帧空间和输出数据三部分。 第 2 章 复杂度分析 hello‑algo.com 40 图 2‑150 码力 | 376 页 | 30.67 MB | 1 年前3
Hello 算法 1.2.0 繁体中文 Dart 版… , ???] ,則該選擇序列 需要滿足 ?1 ≤ ?2 ≤ ⋯ ≤ ?? ,不滿足該條件的選擇序列都會造成重複,應當剪枝。 3. 程式碼實現 為實現該剪枝,我們初始化變數 start ,用於指示走訪起始點。當做出選擇 ?? 後,設定下一輪從索引 ? 開始 走訪。這樣做就可以讓選擇序列滿足 ?1 ≤ ?2 ≤ ⋯ ≤ ?? ,從而保證子集唯一。 除此之外,我們還對程式碼進行了以下兩項最佳化。 輪中只能被選擇一次,這通常藉助一個雜湊集合來實現。 ‧ 子集和問題的目標是在給定集合中找到和為目標值的所有子集。集合不區分元素順序,而搜尋過程會 輸出所有順序的結果,產生重複子集。我們在回溯前將資料進行排序,並設定一個變數來指示每一輪的 走訪起始點,從而將生成重複子集的搜尋分支進行剪枝。 ‧ 對於子集和問題,陣列中的相等元素會產生重複集合。我們利用陣列已排序的前置條件,透過判斷相鄰 元素是否相等實現剪枝,從而確保相等元素在每輪中只能被選中一次。 方。該問題的約束條件有行約束、列約束、主對角線和次對角線約束。為滿足行約束,我們採用按行放 置的策略,保證每一行放置一個皇后。 ‧ 列約束和對角線約束的處理方式類似。對於列約束,我們利用一個陣列來記錄每一列是否有皇后,從而 指示選中的格子是否合法。對於對角線約束,我們藉助兩個陣列來分別記錄該主、次對角線上是否存在 皇后;難點在於找處在到同一主(副)對角線上格子滿足的行列索引規律。 2. Q & A Q:怎麼理解回溯和遞迴的關係?0 码力 | 378 页 | 18.77 MB | 10 月前3
共 5 条
- 1













