mirror of
https://github.com/krahets/hello-algo.git
synced 2025-11-02 12:58:42 +08:00
Bug fixes and improvements (#1348)
* Add "reference" for EN version. Bug fixes. * Unify the figure reference as "the figure below" and "the figure above". Bug fixes. * Format the EN markdown files. * Replace "" with <u></u> for EN version and bug fixes * Fix biary_tree_dfs.png * Fix biary_tree_dfs.png * Fix zh-hant/biary_tree_dfs.png * Fix heap_sort_step1.png * Sync zh and zh-hant versions. * Bug fixes * Fix EN figures * Bug fixes * Fix the figure labels for EN version
This commit is contained in:
@ -34,7 +34,7 @@ Starting from the original problem $f(0, n-1)$, perform the binary search throug
|
||||
2. Recursively solve the subproblem reduced by half in size, which could be $f(i, m-1)$ or $f(m+1, j)$.
|
||||
3. Repeat steps `1.` and `2.`, until `target` is found or the interval is empty and returns.
|
||||
|
||||
The diagram below shows the divide-and-conquer process of binary search for element $6$ in an array.
|
||||
The figure below shows the divide-and-conquer process of binary search for element $6$ in an array.
|
||||
|
||||

|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
!!! question
|
||||
|
||||
Given the preorder traversal `preorder` and inorder traversal `inorder` of a binary tree, construct the binary tree and return the root node of the binary tree. Assume that there are no duplicate values in the nodes of the binary tree (as shown in the diagram below).
|
||||
Given the preorder traversal `preorder` and inorder traversal `inorder` of a binary tree, construct the binary tree and return the root node of the binary tree. Assume that there are no duplicate values in the nodes of the binary tree (as shown in the figure below).
|
||||
|
||||

|
||||
|
||||
@ -20,10 +20,10 @@ Based on the above analysis, this problem can be solved using divide and conquer
|
||||
|
||||
By definition, `preorder` and `inorder` can be divided into three parts.
|
||||
|
||||
- Preorder traversal: `[ Root | Left Subtree | Right Subtree ]`, for example, the tree in the diagram corresponds to `[ 3 | 9 | 2 1 7 ]`.
|
||||
- Inorder traversal: `[ Left Subtree | Root | Right Subtree ]`, for example, the tree in the diagram corresponds to `[ 9 | 3 | 1 2 7 ]`.
|
||||
- Preorder traversal: `[ Root | Left Subtree | Right Subtree ]`, for example, the tree in the figure corresponds to `[ 3 | 9 | 2 1 7 ]`.
|
||||
- Inorder traversal: `[ Left Subtree | Root | Right Subtree ]`, for example, the tree in the figure corresponds to `[ 9 | 3 | 1 2 7 ]`.
|
||||
|
||||
Using the data in the diagram above, we can obtain the division results as shown in the steps below.
|
||||
Using the data in the figure above, we can obtain the division results as shown in the figure below.
|
||||
|
||||
1. The first element 3 in the preorder traversal is the value of the root node.
|
||||
2. Find the index of the root node 3 in `inorder`, and use this index to divide `inorder` into `[ 9 | 3 | 1 2 7 ]`.
|
||||
@ -49,7 +49,7 @@ As shown in the table below, the above variables can represent the index of the
|
||||
| Left subtree | $i + 1$ | $[l, m-1]$ |
|
||||
| Right subtree | $i + 1 + (m - l)$ | $[m+1, r]$ |
|
||||
|
||||
Please note, the meaning of $(m-l)$ in the right subtree root index is "the number of nodes in the left subtree", which is suggested to be understood in conjunction with the diagram below.
|
||||
Please note, the meaning of $(m-l)$ in the right subtree root index is "the number of nodes in the left subtree", which is suggested to be understood in conjunction with the figure below.
|
||||
|
||||

|
||||
|
||||
@ -61,7 +61,7 @@ To improve the efficiency of querying $m$, we use a hash table `hmap` to store t
|
||||
[file]{build_tree}-[class]{}-[func]{build_tree}
|
||||
```
|
||||
|
||||
The diagram below shows the recursive process of building the binary tree, where each node is established during the "descending" process, and each edge (reference) is established during the "ascending" process.
|
||||
The figure below shows the recursive process of building the binary tree, where each node is established during the "descending" process, and each edge (reference) is established during the "ascending" process.
|
||||
|
||||
=== "<1>"
|
||||

|
||||
@ -90,7 +90,7 @@ The diagram below shows the recursive process of building the binary tree, where
|
||||
=== "<9>"
|
||||

|
||||
|
||||
Each recursive function's division results of `preorder` and `inorder` are shown in the diagram below.
|
||||
Each recursive function's division results of `preorder` and `inorder` are shown in the figure below.
|
||||
|
||||

|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ In both merge sorting and building binary trees, we decompose the original probl
|
||||
|
||||
!!! question
|
||||
|
||||
Given three pillars, denoted as `A`, `B`, and `C`. Initially, pillar `A` is stacked with $n$ discs, arranged in order from top to bottom from smallest to largest. Our task is to move these $n$ discs to pillar `C`, maintaining their original order (as shown below). The following rules must be followed during the disc movement process:
|
||||
Given three pillars, denoted as `A`, `B`, and `C`. Initially, pillar `A` is stacked with $n$ discs, arranged in order from top to bottom from smallest to largest. Our task is to move these $n$ discs to pillar `C`, maintaining their original order (as shown in the figure below). The following rules must be followed during the disc movement process:
|
||||
|
||||
1. A disc can only be picked up from the top of a pillar and placed on top of another pillar.
|
||||
2. Only one disc can be moved at a time.
|
||||
@ -16,7 +16,7 @@ In both merge sorting and building binary trees, we decompose the original probl
|
||||
|
||||
### Consider the base case
|
||||
|
||||
As shown below, for the problem $f(1)$, i.e., when there is only one disc, we can directly move it from `A` to `C`.
|
||||
As shown in the figure below, for the problem $f(1)$, i.e., when there is only one disc, we can directly move it from `A` to `C`.
|
||||
|
||||
=== "<1>"
|
||||

|
||||
@ -24,7 +24,7 @@ As shown below, for the problem $f(1)$, i.e., when there is only one disc, we ca
|
||||
=== "<2>"
|
||||

|
||||
|
||||
As shown below, for the problem $f(2)$, i.e., when there are two discs, **since the smaller disc must always be above the larger disc, `B` is needed to assist in the movement**.
|
||||
As shown in the figure below, for the problem $f(2)$, i.e., when there are two discs, **since the smaller disc must always be above the larger disc, `B` is needed to assist in the movement**.
|
||||
|
||||
1. First, move the smaller disc from `A` to `B`.
|
||||
2. Then move the larger disc from `A` to `C`.
|
||||
@ -48,7 +48,7 @@ The process of solving the problem $f(2)$ can be summarized as: **moving two dis
|
||||
|
||||
For the problem $f(3)$, i.e., when there are three discs, the situation becomes slightly more complicated.
|
||||
|
||||
Since we already know the solutions to $f(1)$ and $f(2)$, we can think from a divide-and-conquer perspective and **consider the two top discs on `A` as a unit**, performing the steps shown below. This way, the three discs are successfully moved from `A` to `C`.
|
||||
Since we already know the solutions to $f(1)$ and $f(2)$, we can think from a divide-and-conquer perspective and **consider the two top discs on `A` as a unit**, performing the steps shown in the figure below. This way, the three discs are successfully moved from `A` to `C`.
|
||||
|
||||
1. Let `B` be the target pillar and `C` the buffer pillar, and move the two discs from `A` to `B`.
|
||||
2. Move the remaining disc from `A` directly to `C`.
|
||||
@ -68,7 +68,7 @@ Since we already know the solutions to $f(1)$ and $f(2)$, we can think from a di
|
||||
|
||||
Essentially, **we divide the problem $f(3)$ into two subproblems $f(2)$ and one subproblem $f(1)$**. By solving these three subproblems in order, the original problem is resolved. This indicates that the subproblems are independent, and their solutions can be merged.
|
||||
|
||||
From this, we can summarize the divide-and-conquer strategy for solving the Tower of Hanoi shown in the following image: divide the original problem $f(n)$ into two subproblems $f(n-1)$ and one subproblem $f(1)$, and solve these three subproblems in the following order.
|
||||
From this, we can summarize the divide-and-conquer strategy for solving the Tower of Hanoi shown in the figure below: divide the original problem $f(n)$ into two subproblems $f(n-1)$ and one subproblem $f(1)$, and solve these three subproblems in the following order.
|
||||
|
||||
1. Move $n-1$ discs with the help of `C` from `A` to `B`.
|
||||
2. Move the remaining one disc directly from `A` to `C`.
|
||||
@ -86,7 +86,7 @@ In the code, we declare a recursive function `dfs(i, src, buf, tar)` whose role
|
||||
[file]{hanota}-[class]{}-[func]{solve_hanota}
|
||||
```
|
||||
|
||||
As shown below, the Tower of Hanoi forms a recursive tree with a height of $n$, each node representing a subproblem, corresponding to an open `dfs()` function, **thus the time complexity is $O(2^n)$, and the space complexity is $O(n)$**.
|
||||
As shown in the figure below, the Tower of Hanoi forms a recursive tree with a height of $n$, each node representing a subproblem, corresponding to an open `dfs()` function, **thus the time complexity is $O(2^n)$, and the space complexity is $O(n)$**.
|
||||
|
||||

|
||||
|
||||
|
||||
Reference in New Issue
Block a user