程序员 · 高频练习

有序数组中存在多个3,二分查找怎样找到最左边的3?

初级 单选题 第 1127 题 较难 程序员二分查找左边界lower_bound有序数组
题目

有序数组为[1,3,3,3,7],要求返回第一个等于3的下标。二分过程中mid位置的值等于3时,下一步应()。

A 立即返回mid,不再检查左侧
B 只向右半区查找
C 记录mid为候选答案,并继续收缩右边界到左半区寻找更早的3
D 把数组改成无序后重新遍历
题目类型:原创高频练习题 用途:用于帮助理解程序员相关考点和答案解析,不等同于官方真题。
正确答案
C
答案解析

普通二分找到任意一个3即可返回,但左边界问题还要排除左侧存在相同值。命中后保留候选位置并令右边界左移,直到搜索区间结束。

选项分析

A

错误。可能返回下标2或3,而不是最左下标1。

B

错误。目标是更左位置,命中后不应只往右。

C

正确。记录答案并继续压缩右边界。

D

错误。破坏有序性会丢失二分查找条件。

本题为什么容易错

许多代码模板能找到一个目标值,却没有写清要找哪一个。题目一旦出现第一个、最后一个、插入位置,命中后的动作就变了。

先看结论

简短答案

有序数组中存在多个3,二分查找怎样找到最左边的3,正确答案是 C(记录mid为候选答案,并继续收缩右边界到左半区寻找更早的3)。普通二分找到任意一个3即可返回,但左边界问题还要排除左侧存在相同值。命中后保留候选位置并令右边界左移,直到搜索区间结束。

解析

易混淆概念对比表

概念本题判断区别要点记忆提示
立即返回mid,不再检查左侧 本题干扰项 错误。可能返回下标2或3,而不是最左下标1。 看到该词不要急着选,先判断是否真正解决题干问题
只向右半区查找 本题干扰项 错误。目标是更左位置,命中后不应只往右。 看到该词不要急着选,先判断是否真正解决题干问题
记录mid为候选答案,并继续收缩右边界到左半区寻找更早的3 本题正确答案 正确。记录答案并继续压缩右边界。 看到题干核心场景时优先联想到它
把数组改成无序后重新遍历 本题干扰项 错误。破坏有序性会丢失二分查找条件。 看到该词不要急着选,先判断是否真正解决题干问题
本题易混淆选项怎么区分
  • 立即返回mid,不再检查左侧:错误。可能返回下标2或3,而不是最左下标1。
  • 只向右半区查找:错误。目标是更左位置,命中后不应只往右。
  • 把数组改成无序后重新遍历:错误。破坏有序性会丢失二分查找条件。
复习

知识点详解

一种实现是在值等于target时记录mid并令right=mid-1;另一种是寻找第一个不小于target的位置,循环结束后检查该位置是否越界且值等于target。

备考速记

命中只是找到一个;要找第一个,记下来还得继续往左。

lower_bound 在有序数组场景中的作用

数组[1,3,3,3,7]中,普通二分第一次可能命中下标2;左边界算法继续检查左侧,最后返回下标1。

拓展

同类题怎么考

  • 在重复元素数组中寻找第一个目标值。
  • 根据lower_bound结果判断目标是否存在。
lower_bound 在程序员软考中的考法

看到‘第一个’就不能命中即停。检查代码是否保留候选并继续向左收缩,是最快判断方法。

解题思路

命中只证明‘这里有3’,没有证明‘这里是第一个3’。要继续往左查,若再命中就更新候选,最终留下最左位置,选C。

考点定位

找任意值、找第一个等于、找第一个不小于是三个不同契约。边界更新必须跟函数契约一致。

易错提醒

  • 命中立即返回,重复值时结果不稳定。
  • 使用闭区间循环却按半开区间更新边界,造成死循环。
  • 搜索结束后未验证候选位置确实等于target。

备考提示

  • 先用一句话写清搜索契约,再选择边界模板。
  • 在书木兰软考题库 https://www.shumulan.com/ 练二分题时,可把‘任意命中、左边界、右边界、插入位置’分别放进错题标签。

你可能还想了解

  • 二分查找如何找到第一个3?
  • 命中target后为什么不能立即返回?
  • lower_bound和普通二分有什么区别?

本文小结

寻找第一个等于目标值的位置时,命中mid后要记录候选并继续向左收缩,不能像普通二分一样立即返回。