translation: update binary_search _edge.md

This commit is contained in:
yanedie 2024-12-04 02:06:43 +08:00
parent 6abf0fbdf1
commit 3e44192780

View file

@ -6,9 +6,9 @@
Given a sorted array `nums` of length $n$, which may contain duplicate elements, return the index of the leftmost element `target`. If the element is not present in the array, return $-1$. Given a sorted array `nums` of length $n$, which may contain duplicate elements, return the index of the leftmost element `target`. If the element is not present in the array, return $-1$.
Recall the method of binary search for an insertion point, after the search is completed, $i$ points to the leftmost `target`, **thus searching for the insertion point is essentially searching for the index of the leftmost `target`**. Look back on the method of binary search for an insertion point, after the search is completed, the index $i$ will point to the leftmost occurrence of `target`. Therefore, **searching for the insertion point is essentially the same as finding the index of the leftmost `target`**.
Consider implementing the search for the left boundary using the function for finding an insertion point. Note that the array might not contain `target`, which could lead to the following two results: We can use the function for finding an insertion point to find the left boundary of `target`. Note that the array might not contain `target`, which could lead to the following two results:
- The index $i$ of the insertion point is out of bounds. - The index $i$ of the insertion point is out of bounds.
- The element `nums[i]` is not equal to `target`. - The element `nums[i]` is not equal to `target`.
@ -21,27 +21,27 @@ In these cases, simply return $-1$. The code is as follows:
## Find the right boundary ## Find the right boundary
So how do we find the rightmost `target`? The most straightforward way is to modify the code, replacing the pointer contraction operation in the case of `nums[m] == target`. The code is omitted here, but interested readers can implement it on their own. How do we find the rightmost occurrence of `target`? The most straightforward way is to modify the traditional binary search logic by changing how we adjust the search boundaries in the case of `nums[m] == target`. The code is omitted here. If you are interested, try to implement the code on your own.
Below we introduce two more cunning methods. Below we are going to introduce two more ingenious methods.
### Reusing the search for the left boundary ### Reuse the left boundary search
In fact, we can use the function for finding the leftmost element to find the rightmost element, specifically by **transforming the search for the rightmost `target` into a search for the leftmost `target + 1`**. To find the rightmost occurrence of `target`, we can reuse the logic for finding the leftmost occurrence of `target`. Specifically, we can find the leftmost `target`, and then adjust the result to point to the rightmost `target` by simply adding 1 to the index of the leftmost `target`.
As shown in the figure below, after the search is completed, the pointer $i$ points to the leftmost `target + 1` (if it exists), while $j$ points to the rightmost `target`, **thus returning $j$ is sufficient**. As shown in the figure below, after the search is complete, pointer $i$ will point to the the position just after the leftmost `target` (i.e., `target + 1`), and pointer $j$ will point to the rightmost `target`. Therefore, returning $j$ will give us the right boundary.
![Transforming the search for the right boundary into the search for the left boundary](binary_search_edge.assets/binary_search_right_edge_by_left_edge.png) ![Transforming the search for the right boundary into the search for the left boundary](binary_search_edge.assets/binary_search_right_edge_by_left_edge.png)
Please note, the insertion point returned is $i$, therefore, it should be subtracted by $1$ to obtain $j$: Note that the insertion point returned is $i$, therefore, it should be subtracted by $1$ to obtain $j$:
```src ```src
[file]{binary_search_edge}-[class]{}-[func]{binary_search_right_edge} [file]{binary_search_edge}-[class]{}-[func]{binary_search_right_edge}
``` ```
### Transforming into an element search ### Transform into an element search
We know that when the array does not contain `target`, $i$ and $j$ will eventually point to the first element greater and smaller than `target` respectively. When the array does not contain `target`, $i$ and $j$ will eventually point to the first element greater and smaller than `target` respectively.
Thus, as shown in the figure below, we can construct an element that does not exist in the array, to search for the left and right boundaries. Thus, as shown in the figure below, we can construct an element that does not exist in the array, to search for the left and right boundaries.
@ -50,7 +50,7 @@ Thus, as shown in the figure below, we can construct an element that does not ex
![Transforming the search for boundaries into the search for an element](binary_search_edge.assets/binary_search_edge_by_element.png) ![Transforming the search for boundaries into the search for an element](binary_search_edge.assets/binary_search_edge_by_element.png)
The code is omitted here, but two points are worth noting. The code is omitted here, but here are two important points to note about this approach.
- The given array does not contain decimals, meaning we do not need to worry about how to handle equal situations. - Since the given array does not contain decimals, this means we do not need to worry about handling equal cases.
- Since this method introduces decimals, the variable `target` in the function needs to be changed to a floating point type (no change needed in Python). - Because this method introduces decimals, the variable `target` in the function needs to be changed to a floating point type (no change needed in Python).