mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-20 02:26:11 +00:00
build
This commit is contained in:
@@ -38,7 +38,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.
|
||||
Figure 12-4 shows the divide-and-conquer process of binary search for element $6$ in an array.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -76,9 +76,32 @@ In the implementation code, we declare a recursive function `dfs()` to solve the
|
||||
=== "C++"
|
||||
|
||||
```cpp title="binary_search_recur.cpp"
|
||||
[class]{}-[func]{dfs}
|
||||
/* Binary search: problem f(i, j) */
|
||||
int dfs(vector<int> &nums, int target, int i, int j) {
|
||||
// If the interval is empty, indicating no target element, return -1
|
||||
if (i > j) {
|
||||
return -1;
|
||||
}
|
||||
// Calculate midpoint index m
|
||||
int m = (i + j) / 2;
|
||||
if (nums[m] < target) {
|
||||
// Recursive subproblem f(m+1, j)
|
||||
return dfs(nums, target, m + 1, j);
|
||||
} else if (nums[m] > target) {
|
||||
// Recursive subproblem f(i, m-1)
|
||||
return dfs(nums, target, i, m - 1);
|
||||
} else {
|
||||
// Found the target element, thus return its index
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
[class]{}-[func]{binarySearch}
|
||||
/* Binary search */
|
||||
int binarySearch(vector<int> &nums, int target) {
|
||||
int n = nums.size();
|
||||
// Solve problem f(0, n-1)
|
||||
return dfs(nums, target, 0, n - 1);
|
||||
}
|
||||
```
|
||||
|
||||
=== "Java"
|
||||
|
||||
@@ -6,7 +6,7 @@ comments: true
|
||||
|
||||
!!! 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 Figure 12-5).
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -26,10 +26,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 Figure 12-6.
|
||||
|
||||
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 ]`.
|
||||
@@ -61,7 +61,7 @@ As shown in Table 12-1, the above variables can represent the index of the root
|
||||
|
||||
</div>
|
||||
|
||||
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 Figure 12-7.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -107,9 +107,33 @@ To improve the efficiency of querying $m$, we use a hash table `hmap` to store t
|
||||
=== "C++"
|
||||
|
||||
```cpp title="build_tree.cpp"
|
||||
[class]{}-[func]{dfs}
|
||||
/* Build binary tree: Divide and conquer */
|
||||
TreeNode *dfs(vector<int> &preorder, unordered_map<int, int> &inorderMap, int i, int l, int r) {
|
||||
// Terminate when subtree interval is empty
|
||||
if (r - l < 0)
|
||||
return NULL;
|
||||
// Initialize root node
|
||||
TreeNode *root = new TreeNode(preorder[i]);
|
||||
// Query m to divide left and right subtrees
|
||||
int m = inorderMap[preorder[i]];
|
||||
// Subproblem: build left subtree
|
||||
root->left = dfs(preorder, inorderMap, i + 1, l, m - 1);
|
||||
// Subproblem: build right subtree
|
||||
root->right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r);
|
||||
// Return root node
|
||||
return root;
|
||||
}
|
||||
|
||||
[class]{}-[func]{buildTree}
|
||||
/* Build binary tree */
|
||||
TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
|
||||
// Initialize hash table, storing in-order elements to indices mapping
|
||||
unordered_map<int, int> inorderMap;
|
||||
for (int i = 0; i < inorder.size(); i++) {
|
||||
inorderMap[inorder[i]] = i;
|
||||
}
|
||||
TreeNode *root = dfs(preorder, inorderMap, 0, 0, inorder.size() - 1);
|
||||
return root;
|
||||
}
|
||||
```
|
||||
|
||||
=== "Java"
|
||||
@@ -232,7 +256,7 @@ To improve the efficiency of querying $m$, we use a hash table `hmap` to store t
|
||||
[class]{}-[func]{buildTree}
|
||||
```
|
||||
|
||||
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.
|
||||
Figure 12-8 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>"
|
||||
{ class="animation-figure" }
|
||||
@@ -263,7 +287,7 @@ The diagram below shows the recursive process of building the binary tree, where
|
||||
|
||||
<p align="center"> Figure 12-8 Recursive process of building a binary tree </p>
|
||||
|
||||
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 Figure 12-9.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
|
||||
@@ -129,11 +129,36 @@ In the code, we declare a recursive function `dfs(i, src, buf, tar)` whose role
|
||||
=== "C++"
|
||||
|
||||
```cpp title="hanota.cpp"
|
||||
[class]{}-[func]{move}
|
||||
/* Move a disc */
|
||||
void move(vector<int> &src, vector<int> &tar) {
|
||||
// Take out a disc from the top of src
|
||||
int pan = src.back();
|
||||
src.pop_back();
|
||||
// Place the disc on top of tar
|
||||
tar.push_back(pan);
|
||||
}
|
||||
|
||||
[class]{}-[func]{dfs}
|
||||
/* Solve the Tower of Hanoi problem f(i) */
|
||||
void dfs(int i, vector<int> &src, vector<int> &buf, vector<int> &tar) {
|
||||
// If only one disc remains on src, move it to tar
|
||||
if (i == 1) {
|
||||
move(src, tar);
|
||||
return;
|
||||
}
|
||||
// Subproblem f(i-1): move the top i-1 discs from src with the help of tar to buf
|
||||
dfs(i - 1, src, tar, buf);
|
||||
// Subproblem f(1): move the remaining one disc from src to tar
|
||||
move(src, tar);
|
||||
// Subproblem f(i-1): move the top i-1 discs from buf with the help of src to tar
|
||||
dfs(i - 1, buf, src, tar);
|
||||
}
|
||||
|
||||
[class]{}-[func]{solveHanota}
|
||||
/* Solve the Tower of Hanoi problem */
|
||||
void solveHanota(vector<int> &A, vector<int> &B, vector<int> &C) {
|
||||
int n = A.size();
|
||||
// Move the top n discs from A with the help of B to C
|
||||
dfs(n, A, B, C);
|
||||
}
|
||||
```
|
||||
|
||||
=== "Java"
|
||||
|
||||
Reference in New Issue
Block a user