二分查找可精准定位排序数组中目标元素的第一个、最后一个或任意满足条件的位置;核心是利用有序性缩小区间,标准流程为设left=0、right=n−1,循环中计算mid=left+(right−left)/2,根据比较结果更新边界,最终返回下标或验证存在性。

二分查找解决排序数组中元素位置问题,核心是利用数组有序性,通过不断缩小区间逼近目标。它不只用于“是否存在”,更可精准定位第一个、最后一个或任意满足条件的位置。
标准查找:判断存在并返回任意一个下标
适用于数组无重复或只需任一匹配位置的场景。每次比较后明确舍弃一半区间:
- 设 left = 0,right = n−1
- 循环条件为 left ≤ right
- 计算 mid = left + (right − left) / 2(避免整型溢出)
- 若 nums[mid] == target,直接返回 mid
- 若 nums[mid] > target,说明目标在左半段,令 right = mid − 1
- 若 nums[mid] ,说明目标在右半段,令 left = mid + 1
- 循环结束仍未找到,返回 −1
查找第一个位置:收缩右边界
当目标值重复出现时,要找最左侧下标。关键在于:遇到 nums[mid] ≥ target 时,不能排除 mid 本身,需保留并继续向左试探:
- 循环条件仍为 left (避免死循环)
- mid 取偏左值:mid = left + (right − left) / 2
- 若 nums[mid] ,说明左段全小,left = mid + 1
- 若 nums[mid] ≥ target,说明答案在 [left, mid] 内,right = mid
- 退出后检查 nums[left] == target,否则返回 −1
查找最后一个位置:收缩左边界
对应最右侧下标。逻辑对称:遇到 nums[mid] ≤ target 时保留 mid,向右试探:
- 同样用 left 循环
- mid 需偏右(避免卡住):mid = left + (right − left + 1) / 2
- 若 nums[mid] > target,说明右段全大,right = mid − 1
- 若 nums[mid] ≤ target,说明答案在 [mid, right] 内,left = mid
- 退出后验证是否匹配
统一模板与注意事项
两次独立二分(先左端点、再右端点)即可得完整范围,时间复杂度稳定 O(log n)。实际编码中需注意:
- 初始边界必须覆盖整个数组,right 初始化为 nums.size() − 1
- mid 计算一律用 left + (right − left) / 2 或其变体,杜绝 (left + right) / 2 溢出风险
- 循环终止条件根据收缩方向选择:left 更适配边界查找,left ≤ right 更适配存在性判断
- 最终必须校验 nums[left] 或 nums[right] 是否真等于 target,防止越界或误判


















