diff --git a/chapter_divide_and_conquer/build_binary_tree_problem.md b/chapter_divide_and_conquer/build_binary_tree_problem.md index 1f1d85099..d28850e53 100644 --- a/chapter_divide_and_conquer/build_binary_tree_problem.md +++ b/chapter_divide_and_conquer/build_binary_tree_problem.md @@ -429,11 +429,14 @@ status: new === "<9>" ![built_tree_step9](build_binary_tree_problem.assets/built_tree_step9.png) -=== "<10>" - ![built_tree_step10](build_binary_tree_problem.assets/built_tree_step10.png) -

图 12-8   构建二叉树的递归过程

+每个递归函数内的前序遍历 `preorder` 和中序遍历 `inorder` 的划分结果如图 12-9 所示。 + +![built_tree_overall](build_binary_tree_problem.assets/built_tree_overall.png) + +

图 12-9   built_tree_overall

+ 设树的节点数量为 $n$ ,初始化每一个节点(执行一个递归函数 `dfs()` )使用 $O(1)$ 时间。**因此总体时间复杂度为 $O(n)$** 。 哈希表存储 `inorder` 元素到索引的映射,空间复杂度为 $O(n)$ 。最差情况下,即二叉树退化为链表时,递归深度达到 $n$ ,使用 $O(n)$ 的栈帧空间。**因此总体空间复杂度为 $O(n)$** 。 diff --git a/chapter_divide_and_conquer/hanota_problem.md b/chapter_divide_and_conquer/hanota_problem.md index 04c85246e..95d20da0f 100644 --- a/chapter_divide_and_conquer/hanota_problem.md +++ b/chapter_divide_and_conquer/hanota_problem.md @@ -17,13 +17,13 @@ status: new ![汉诺塔问题示例](hanota_problem.assets/hanota_example.png) -

图 12-9   汉诺塔问题示例

+

图 12-10   汉诺塔问题示例

**我们将规模为 $i$ 的汉诺塔问题记做 $f(i)$** 。例如 $f(3)$ 代表将 $3$ 个圆盘从 `A` 移动至 `C` 的汉诺塔问题。 ### 1.   考虑基本情况 -如图 12-10 所示,对于问题 $f(1)$ ,即当只有一个圆盘时,我们将它直接从 `A` 移动至 `C` 即可。 +如图 12-11 所示,对于问题 $f(1)$ ,即当只有一个圆盘时,我们将它直接从 `A` 移动至 `C` 即可。 === "<1>" ![规模为 1 问题的解](hanota_problem.assets/hanota_f1_step1.png) @@ -31,9 +31,9 @@ status: new === "<2>" ![hanota_f1_step2](hanota_problem.assets/hanota_f1_step2.png) -

图 12-10   规模为 1 问题的解

+

图 12-11   规模为 1 问题的解

-如图 12-11 所示,对于问题 $f(2)$ ,即当有两个圆盘时,**由于要时刻满足小圆盘在大圆盘之上,因此需要借助 `B` 来完成移动**。 +如图 12-12 所示,对于问题 $f(2)$ ,即当有两个圆盘时,**由于要时刻满足小圆盘在大圆盘之上,因此需要借助 `B` 来完成移动**。 1. 先将上面的小圆盘从 `A` 移至 `B` 。 2. 再将大圆盘从 `A` 移至 `C` 。 @@ -51,7 +51,7 @@ status: new === "<4>" ![hanota_f2_step4](hanota_problem.assets/hanota_f2_step4.png) -

图 12-11   规模为 2 问题的解

+

图 12-12   规模为 2 问题的解

解决问题 $f(2)$ 的过程可总结为:**将两个圆盘借助 `B` 从 `A` 移至 `C`** 。其中,`C` 称为目标柱、`B` 称为缓冲柱。 @@ -59,7 +59,7 @@ status: new 对于问题 $f(3)$ ,即当有三个圆盘时,情况变得稍微复杂了一些。 -因为已知 $f(1)$ 和 $f(2)$ 的解,所以我们可从分治角度思考,**将 `A` 顶部的两个圆盘看做一个整体**,执行图 12-12 所示的步骤。这样三个圆盘就被顺利地从 `A` 移动至 `C` 了。 +因为已知 $f(1)$ 和 $f(2)$ 的解,所以我们可从分治角度思考,**将 `A` 顶部的两个圆盘看做一个整体**,执行图 12-13 所示的步骤。这样三个圆盘就被顺利地从 `A` 移动至 `C` 了。 1. 令 `B` 为目标柱、`C` 为缓冲柱,将两个圆盘从 `A` 移动至 `B` 。 2. 将 `A` 中剩余的一个圆盘从 `A` 直接移动至 `C` 。 @@ -77,11 +77,11 @@ status: new === "<4>" ![hanota_f3_step4](hanota_problem.assets/hanota_f3_step4.png) -

图 12-12   规模为 3 问题的解

+

图 12-13   规模为 3 问题的解

本质上看,**我们将问题 $f(3)$ 划分为两个子问题 $f(2)$ 和子问题 $f(1)$** 。按顺序解决这三个子问题之后,原问题随之得到解决。这说明子问题是独立的,而且解是可以合并的。 -至此,我们可总结出图 12-13 所示的汉诺塔问题的分治策略:将原问题 $f(n)$ 划分为两个子问题 $f(n-1)$ 和一个子问题 $f(1)$ ,并按照以下顺序解决这三个子问题。 +至此,我们可总结出图 12-14 所示的汉诺塔问题的分治策略:将原问题 $f(n)$ 划分为两个子问题 $f(n-1)$ 和一个子问题 $f(1)$ ,并按照以下顺序解决这三个子问题。 1. 将 $n-1$ 个圆盘借助 `C` 从 `A` 移至 `B` 。 2. 将剩余 $1$ 个圆盘从 `A` 直接移至 `C` 。 @@ -91,7 +91,7 @@ status: new ![汉诺塔问题的分治策略](hanota_problem.assets/hanota_divide_and_conquer.png) -

图 12-13   汉诺塔问题的分治策略

+

图 12-14   汉诺塔问题的分治策略

### 3.   代码实现 @@ -433,11 +433,11 @@ status: new } ``` -如图 12-14 所示,汉诺塔问题形成一个高度为 $n$ 的递归树,每个节点代表一个子问题、对应一个开启的 `dfs()` 函数,**因此时间复杂度为 $O(2^n)$ ,空间复杂度为 $O(n)$** 。 +如图 12-15 所示,汉诺塔问题形成一个高度为 $n$ 的递归树,每个节点代表一个子问题、对应一个开启的 `dfs()` 函数,**因此时间复杂度为 $O(2^n)$ ,空间复杂度为 $O(n)$** 。 ![汉诺塔问题的递归树](hanota_problem.assets/hanota_recursive_tree.png) -

图 12-14   汉诺塔问题的递归树

+

图 12-15   汉诺塔问题的递归树

!!! quote diff --git a/chapter_greedy/max_product_cutting_problem.md b/chapter_greedy/max_product_cutting_problem.md index 8c31e771b..e53fdd988 100644 --- a/chapter_greedy/max_product_cutting_problem.md +++ b/chapter_greedy/max_product_cutting_problem.md @@ -53,7 +53,7 @@ $$ **贪心策略二**:在切分方案中,最多只应存在两个 $2$ 。因为三个 $2$ 总是可以被替换为两个 $3$ ,从而获得更大乘积。 -![最优切分因子](max_product_cutting_problem.assets/max_product_cutting_greedy_infer3.png) +![最优切分因子](max_product_cutting_problem.assets/max_product_cutting_greedy_infer2.png)

图 15-15   最优切分因子

diff --git a/chapter_introduction/algorithms_are_everywhere.md b/chapter_introduction/algorithms_are_everywhere.md index 235b2d976..59401608f 100644 --- a/chapter_introduction/algorithms_are_everywhere.md +++ b/chapter_introduction/algorithms_are_everywhere.md @@ -15,19 +15,19 @@ comments: true 3. 不断重复步骤 `1.` 和 步骤 `2.` ,直至找到拼音首字母为 $r$ 的页码为止。 === "<1>" - ![查字典步骤](algorithms_are_everywhere.assets/binary_search_dictionary_step_1.png) + ![查字典步骤](algorithms_are_everywhere.assets/binary_search_dictionary_step1.png) === "<2>" - ![binary_search_dictionary_step_2](algorithms_are_everywhere.assets/binary_search_dictionary_step_2.png) + ![binary_search_dictionary_step2](algorithms_are_everywhere.assets/binary_search_dictionary_step2.png) === "<3>" - ![binary_search_dictionary_step_3](algorithms_are_everywhere.assets/binary_search_dictionary_step_3.png) + ![binary_search_dictionary_step3](algorithms_are_everywhere.assets/binary_search_dictionary_step3.png) === "<4>" - ![binary_search_dictionary_step_4](algorithms_are_everywhere.assets/binary_search_dictionary_step_4.png) + ![binary_search_dictionary_step4](algorithms_are_everywhere.assets/binary_search_dictionary_step4.png) === "<5>" - ![binary_search_dictionary_step_5](algorithms_are_everywhere.assets/binary_search_dictionary_step_5.png) + ![binary_search_dictionary_step5](algorithms_are_everywhere.assets/binary_search_dictionary_step5.png)

图 1-1   查字典步骤