Files
hello-algo/en/docs/chapter_searching/binary_search_edge.md
Yudong Jin 2778a6f9c7 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
2025-12-31 07:44:52 +08:00

3.0 KiB

Binary Search Edge Cases

Finding the Left Boundary

!!! question

Given a sorted array `nums` of length $n$ that may contain duplicate elements, return the index of the leftmost element `target` in the array. If the array does not contain the element, return $-1$.

Recall the method for finding the insertion point with binary search. After the search completes, i points to the leftmost target, so finding the insertion point is essentially finding the index of the leftmost target.

Consider implementing the left boundary search using the insertion point finding function. Note that the array may not contain target, which could result in the following two cases:

  • The insertion point index i is out of bounds.
  • The element nums[i] is not equal to target.

When either of these situations occurs, simply return -1. The code is shown below:

[file]{binary_search_edge}-[class]{}-[func]{binary_search_left_edge}

Finding the Right Boundary

So how do we find the rightmost target? The most direct approach is to modify the code and replace the pointer shrinking operation in the nums[m] == target case. The code is omitted here; interested readers can implement it themselves.

Below we introduce two more clever methods.

In fact, we can use the function for finding the leftmost element to find the rightmost element. The specific method is: Convert finding the rightmost target into finding the leftmost target + 1.

As shown in the figure below, after the search completes, pointer i points to the leftmost target + 1 (if it exists), while j points to the rightmost target, so we can simply return $j$.

Converting right boundary search to left boundary search

Note that the returned insertion point is i, so we need to subtract 1 from it to obtain j:

[file]{binary_search_edge}-[class]{}-[func]{binary_search_right_edge}

We know that when the array does not contain target, i and j will eventually point to the first elements greater than and less than target, respectively.

Therefore, as shown in the figure below, we can construct an element that does not exist in the array to find the left and right boundaries.

  • Finding the leftmost target: Can be converted to finding target - 0.5 and returning pointer i.
  • Finding the rightmost target: Can be converted to finding target + 0.5 and returning pointer j.

Converting boundary search to element search

The code is omitted here, but the following two points are worth noting:

  • Since the given array does not contain decimals, we don't need to worry about how to handle equal cases.
  • Because this method introduces decimals, the variable target in the function needs to be changed to a floating-point type (Python does not require this change).