正文
当数组中存在重复元素时,标准的二分查找只能随机返回其中一个目标的索引。如果我们需要找到第一个出现的目标元素(最左侧边界),或者目标不存在时其应插入的位置,需要使用以下变体。
算法模板
1 | fun searchLeftBound(nums: IntArray, target: Int): Int { |
使用说明
核心逻辑:
- 关键在于
nums[mid] >= target时执行right = mid - 1。即使找到了目标,我们也并不立即返回,而是继续收缩右边界,试图在左侧找到更早出现的目标。 - 循环结束后,
left变量的值即为大于等于target的第一个元素的索引。
- 关键在于
适用场景:
- 查找有序数组中第一个等于
target的元素。 - 查找第一个大于等于
target的元素(Lower Bound)。 - 统计重复元素的个数(通过左右边界相减)。
- 查找有序数组中第一个等于
注意点:
- 返回值
left的范围是[0, nums.size]。如果target比数组所有元素都大,left将等于nums.size。 - 检查是否存在时,务必先判断
left < nums.size。
- 返回值