* Update giscus scroller. * Refine English docs and landing page * Sync the headings. * Update landing pages. * Update the avatar * Update Acknowledgements * Update landing pages. * Update contributors. * Update * Fix the formula formatting. * Fix the glossary. * Chapter 6. Hashing * Remove Chinese chars. * Fix headings. * Update giscus themes. * fallback to default giscus theme to solve 429 many requests error. * Add borders for callouts. * docs: sync character encoding translations * Update landing page media layout and i18n
5.6 KiB
Binary Search Insertion Point
Binary search can be used not only to search for target elements, but also to solve many variant problems, such as finding the insertion position of a target element.
Case Without Duplicate Elements
!!! question
Given a sorted array `nums` of length $n$ and an element `target`, where the array contains no duplicate elements, insert `target` into `nums` while maintaining its sorted order. If `target` already exists in the array, insert it to its left. Return the index of `target` after insertion. An example is shown below.
If we want to reuse the binary search code from the previous section, we need to answer the following two questions.
Question 1: When the array contains target, is the insertion point index the same as that element's index?
The problem requires inserting target to the left of equal elements, which means the newly inserted target replaces the position of the original target. In other words, when the array contains target, the insertion point index is the index of that target.
Question 2: When the array does not contain target, what is the insertion point index?
To analyze this further, consider the binary search process: when nums[m] < target, i moves, meaning that pointer i is approaching elements greater than or equal to target. Similarly, pointer j is always approaching elements less than or equal to target.
Therefore, when the binary search ends, i must point to the first element greater than target, and j must point to the first element less than target. It follows that when the array does not contain target, the insertion index is $i$. The code is shown below:
[file]{binary_search_insertion}-[class]{}-[func]{binary_search_insertion_simple}
Case with Duplicate Elements
!!! question
Based on the previous problem, assume the array may contain duplicate elements, with everything else remaining the same.
Suppose there are multiple target elements in the array. Ordinary binary search can only return the index of one target, and cannot determine how many target elements are to the left and right of that element.
The problem requires inserting the target element at the leftmost position, so we need to find the index of the leftmost target in the array. A straightforward initial approach is to follow the steps shown in the figure below:
- Perform binary search to obtain the index of any
target, denoted ask. - Starting from index
k, perform linear traversal to the left, and return when the leftmosttargetis found.
Although this method works, it includes linear search, resulting in a time complexity of O(n). When the array contains many duplicate target elements, this method is very inefficient.
Now consider extending the binary search code. As shown in the figure below, the overall process remains unchanged: in each iteration, we first compute the midpoint index m, then compare target with nums[m], leading to the following cases:
- When
nums[m] < targetornums[m] > target, it meanstargethas not been found yet, so use the standard interval-shrinking operation of binary search to move pointersiandjcloser totarget. - When
nums[m] == target, it means elements less thantargetare in the interval[i, m - 1], so usej = m - 1to shrink the interval, thereby moving pointerjcloser to elements less thantarget.
After the loop completes, i points to the leftmost target, and j points to the first element less than target, so index i is the insertion point.
Observe the following code: the branches nums[m] > target and nums[m] == target perform the same operation, so they can be merged.
Even so, we can still keep the conditional branches expanded, as the logic is clearer and more readable.
[file]{binary_search_insertion}-[class]{}-[func]{binary_search_insertion}
!!! tip
The code in this section uses the "closed interval" approach throughout. Interested readers can implement the "left-closed, right-open" approach themselves.
Overall, binary search is simply a matter of setting separate search targets for pointers i and j. The target may be a specific element (such as target) or a range of elements (such as elements less than target).
With each iteration of binary search, pointers i and j gradually approach their preset targets. Ultimately, they either find the answer or stop after crossing the boundary.









