mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-10 11:00:59 +00:00
Translate all code to English (#1836)
* Review the EN heading format. * Fix pythontutor headings. * Fix pythontutor headings. * bug fixes * Fix headings in **/summary.md * Revisit the CN-to-EN translation for Python code using Claude-4.5 * Revisit the CN-to-EN translation for Java code using Claude-4.5 * Revisit the CN-to-EN translation for Cpp code using Claude-4.5. * Fix the dictionary. * Fix cpp code translation for the multipart strings. * Translate Go code to English. * Update workflows to test EN code. * Add EN translation for C. * Add EN translation for CSharp. * Add EN translation for Swift. * Trigger the CI check. * Revert. * Update en/hash_map.md * Add the EN version of Dart code. * Add the EN version of Kotlin code. * Add missing code files. * Add the EN version of JavaScript code. * Add the EN version of TypeScript code. * Fix the workflows. * Add the EN version of Ruby code. * Add the EN version of Rust code. * Update the CI check for the English version code. * Update Python CI check. * Fix cmakelists for en/C code. * Fix Ruby comments
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Divide and conquer search strategy
|
||||
# Divide and Conquer Search Strategy
|
||||
|
||||
We have already learned that search algorithms are divided into two major categories.
|
||||
|
||||
@@ -18,7 +18,7 @@ The divide and conquer strategy of binary search is as follows.
|
||||
|
||||
Divide and conquer can improve search efficiency because brute-force search can only eliminate one option per round, **while divide and conquer search can eliminate half of the options per round**.
|
||||
|
||||
### Implementing binary search based on divide and conquer
|
||||
### Implementing Binary Search Based on Divide and Conquer
|
||||
|
||||
In previous sections, binary search was implemented based on iteration. Now we implement it based on divide and conquer (recursion).
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Building a binary tree problem
|
||||
# Building a Binary Tree Problem
|
||||
|
||||
!!! question
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||

|
||||
|
||||
### Determining if it is a divide and conquer problem
|
||||
### Determining If It Is a Divide and Conquer Problem
|
||||
|
||||
The original problem is defined as constructing a binary tree from `preorder` and `inorder`, which is a typical divide and conquer problem.
|
||||
|
||||
@@ -14,7 +14,7 @@ The original problem is defined as constructing a binary tree from `preorder` an
|
||||
- **Subproblems are independent**: The left and right subtrees are independent of each other; there is no overlap between them. When constructing the left subtree, we only need to focus on the parts of the inorder and preorder traversals corresponding to the left subtree. The same applies to the right subtree.
|
||||
- **Solutions of subproblems can be merged**: Once we have the left and right subtrees (solutions of subproblems), we can link them to the root node to obtain the solution to the original problem.
|
||||
|
||||
### How to divide subtrees
|
||||
### How to Divide Subtrees
|
||||
|
||||
Based on the above analysis, this problem can be solved using divide and conquer, **but how do we divide the left and right subtrees through the preorder traversal `preorder` and inorder traversal `inorder`**?
|
||||
|
||||
@@ -31,7 +31,7 @@ Using the data from the figure above as an example, we can obtain the division r
|
||||
|
||||

|
||||
|
||||
### Describing subtree intervals based on variables
|
||||
### Describing Subtree Intervals Based on Variables
|
||||
|
||||
Based on the above division method, **we have obtained the index intervals of the root node, left subtree, and right subtree in `preorder` and `inorder`**. To describe these index intervals, we need to use several pointer variables.
|
||||
|
||||
@@ -53,7 +53,7 @@ Please note that $(m-l)$ in the right subtree root node index means "the number
|
||||
|
||||

|
||||
|
||||
### Code implementation
|
||||
### Code Implementation
|
||||
|
||||
To improve the efficiency of querying $m$, we use a hash table `hmap` to store the mapping from elements in the `inorder` array to their indices:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Divide and conquer algorithms
|
||||
# Divide and Conquer Algorithms
|
||||
|
||||
<u>Divide and conquer</u> is a very important and common algorithm strategy. Divide and conquer is typically implemented based on recursion, consisting of two steps: "divide" and "conquer".
|
||||
|
||||
@@ -12,7 +12,7 @@ As shown in the figure below, "merge sort" is one of the typical applications of
|
||||
|
||||

|
||||
|
||||
## How to determine divide and conquer problems
|
||||
## How to Determine Divide and Conquer Problems
|
||||
|
||||
Whether a problem is suitable for solving with divide and conquer can usually be determined based on the following criteria.
|
||||
|
||||
@@ -26,13 +26,13 @@ Clearly, merge sort satisfies these three criteria.
|
||||
2. **Subproblems are independent**: Each subarray can be sorted independently (subproblems can be solved independently).
|
||||
3. **Solutions of subproblems can be merged**: Two sorted subarrays (solutions of subproblems) can be merged into one sorted array (solution of the original problem).
|
||||
|
||||
## Improving efficiency through divide and conquer
|
||||
## Improving Efficiency Through Divide and Conquer
|
||||
|
||||
**Divide and conquer can not only effectively solve algorithmic problems but often also improve algorithm efficiency**. In sorting algorithms, quick sort, merge sort, and heap sort are faster than selection, bubble, and insertion sort because they apply the divide and conquer strategy.
|
||||
|
||||
This raises the question: **Why can divide and conquer improve algorithm efficiency, and what is the underlying logic**? In other words, why is dividing a large problem into multiple subproblems, solving the subproblems, and merging their solutions more efficient than directly solving the original problem? This question can be discussed from two aspects: operation count and parallel computation.
|
||||
|
||||
### Operation count optimization
|
||||
### Operation Count Optimization
|
||||
|
||||
Taking "bubble sort" as an example, processing an array of length $n$ requires $O(n^2)$ time. Suppose we divide the array into two subarrays from the midpoint as shown in the figure below, the division requires $O(n)$ time, sorting each subarray requires $O((n / 2)^2)$ time, and merging the two subarrays requires $O(n)$ time, resulting in an overall time complexity of:
|
||||
|
||||
@@ -58,7 +58,7 @@ Going further, **what if we continuously divide the subarrays from their midpoin
|
||||
|
||||
Thinking further, **what if we set multiple division points** and evenly divide the original array into $k$ subarrays? This situation is very similar to "bucket sort", which is well-suited for sorting massive amounts of data, with a theoretical time complexity of $O(n + k)$.
|
||||
|
||||
### Parallel computation optimization
|
||||
### Parallel Computation Optimization
|
||||
|
||||
We know that the subproblems generated by divide and conquer are independent of each other, **so they can typically be solved in parallel**. This means divide and conquer can not only reduce the time complexity of algorithms, **but also benefits from parallel optimization by operating systems**.
|
||||
|
||||
@@ -68,7 +68,7 @@ For example, in the "bucket sort" shown in the figure below, we evenly distribut
|
||||
|
||||

|
||||
|
||||
## Common applications of divide and conquer
|
||||
## Common Applications of Divide and Conquer
|
||||
|
||||
On one hand, divide and conquer can be used to solve many classic algorithmic problems.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Hanota problem
|
||||
# Hanota Problem
|
||||
|
||||
In merge sort and building binary trees, we decompose the original problem into two subproblems, each half the size of the original problem. However, for the hanota problem, we adopt a different decomposition strategy.
|
||||
|
||||
@@ -14,7 +14,7 @@ In merge sort and building binary trees, we decompose the original problem into
|
||||
|
||||
**We denote the hanota problem of size $i$ as $f(i)$**. For example, $f(3)$ represents moving $3$ discs from `A` to `C`.
|
||||
|
||||
### Considering the base cases
|
||||
### Considering the Base Cases
|
||||
|
||||
As shown in the figure below, for problem $f(1)$, when there is only one disc, we can move it directly from `A` to `C`.
|
||||
|
||||
@@ -44,7 +44,7 @@ As shown in the figure below, for problem $f(2)$, when there are two discs, **si
|
||||
|
||||
The process of solving problem $f(2)$ can be summarized as: **moving two discs from `A` to `C` with the help of `B`**. Here, `C` is called the target pillar, and `B` is called the buffer pillar.
|
||||
|
||||
### Subproblem decomposition
|
||||
### Subproblem Decomposition
|
||||
|
||||
For problem $f(3)$, when there are three discs, the situation becomes slightly more complex.
|
||||
|
||||
@@ -78,7 +78,7 @@ For these two subproblems $f(n-1)$, **we can recursively divide them in the same
|
||||
|
||||

|
||||
|
||||
### Code implementation
|
||||
### Code Implementation
|
||||
|
||||
In the code, we declare a recursive function `dfs(i, src, buf, tar)`, whose purpose is to move the top $i$ discs from pillar `src` to target pillar `tar` with the help of buffer pillar `buf`:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Divide and conquer
|
||||
# Divide and Conquer
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Summary
|
||||
|
||||
### Key Review
|
||||
|
||||
- Divide and conquer is a common algorithm design strategy, consisting of two phases: divide (partition) and conquer (merge), typically implemented based on recursion.
|
||||
- The criteria for determining whether a problem is a divide and conquer problem include: whether the problem can be decomposed, whether subproblems are independent, and whether subproblems can be merged.
|
||||
- Merge sort is a typical application of the divide and conquer strategy. It recursively divides an array into two equal-length subarrays until only one element remains, then merges them layer by layer to complete the sorting.
|
||||
|
||||
Reference in New Issue
Block a user